Была создана кнопка (на основе кнопки "добавить заказ") в продажах "Добавить проект". Все работатет отлично, только при создании проекта не проставляется номер проекта. Номер с автоникриментом проставляется на основе статьи https://academy.terrasoft.ru/documents/technic-sdk/7-12/primer-ispolzov…, но там он только при создании проекта из меню и копировании его там, а как сделать что бы при создании проекта через бизнес-процесс проставлялся этот номер?

Нравится

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

Можно как вариант так

В Этой же статье (по ссылке) есть ниже пример "Алгоритм реализации кейса на стороне сервера"  получение номера в событийного подпроцессе.

В этого случая не важно как будет создан объект через клиента или БП, он получит номер в любом случае. Если что то неясно опишите более подробно что вам нужно.

согласно этому коду - номер генерится при наступлении одного из событий "добавление" или "копировании", но процесс создает проект через элемент "добавить данные" а потом открывается на редактирование и при этом не isAddMode() не isCopyMode() не срабатывает и указывают на false, не давая пройти if для генерации номера

"

Прочитайте внимательно мой первый пост.

if (this.isAddMode() || this.isCopyMode()) 
- это относится к варианту когда нумерация сделана
 на клиенте (тобишь при нажатии кнопки сохранить копировать в карточке или реестре)

 Вам нужно посмотреть вторую часть статьи (Листать вниз пока не увидите раздел "Алгоритм реализации кейса на стороне сервера")

 

Те формирование номера можно делать в карточке (на клиенте) при первом сохранении  (this.isAddMode() || this.isCopyMode()) или в событийном БП объекта (При любом создании нового экземпляра объекта) Но не одновременно - это избыточно и не нужно!!!

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

1) сделать 2 сист настройки

2) сделать событийный процесс объекта

3) Опубликуйте 

4) Тестируй

В примере в событийном процессе объекта вы настраиваетесь на событие добавление записи! Она наступает при любом добавлении записи в объект. через механизмы ESQ в том числе через элемент БП добавить данные (как у вас в принскрине все должно быть нормально)!!!!!!

 

Если не получится или не поймещ что делать пиши что сделал по пунктам с принскринами.

 

Прошу прощения, не сообразил сразу, теперь все понял, спасибо я даже как-то не подумал сразу что это сработает

Григорий Чех,

 не работает почему-то

 

Григорий Чех,

Григорий Чех,

Григорий Чех,

Григорий Чех,

 системные настройки не менял, оставил те что были при клиенском коле

Григорий Чех,

 есть один большей минус этого способа по причине него он не подходит "

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

"

1) Напишите как называется ваш проект и какие сис. настройки вы сделали (их имена). Имя системных настроек жестко привязано к имени объекта.

2) В примере для хранения номера  используется поле Code объекта. Если у тебя поле для номера называется по другому UsrNumber в БП должно быть

string.IsNullOrEmpty(Entity.GetTypedColumnValue<string>("UsrNumber "))

 

Entity.SetColumnValue("UsrNumber ", UserTask1.ResultCode);

См статью для понимания где произвести замены

3) В сам объект проект ты добавил событийный процесс в котором перед добавлением записи сделали все по инструкции? Обращаю внимание что все объекты событийного  подпроцесса должны находится в контейнере событийный субпроцесс (Это элемент БП внизу списка найдеш!) На картинке не видно что у тебя подпроцесс в событийном контейнере

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

Григорий Чех,

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

Можно как вариант так

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

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

...
where isActive = 0
...

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

 

Спасибо!

Нравится

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

Сериков Асхат Кайратович,

Если требуется, чтобы записи загружались изначально и фильтр нельзя было отрубить, то в схеме секции:

//можно ещё использовать функцию getFilters
initQueryFilters: function(esq) {
	var filters = this.callParent(arguments);
	//добавляем свои фильтры
	return filters;
}

 

Фильтр?

 

Алексей-Карягин пишет:

Фильтр?

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

Хотелось бы сразу выгружать отфильтрованные данные, а не применять фильтрацию на все данные  

Сериков Асхат Кайратович,

Если требуется, чтобы записи загружались изначально и фильтр нельзя было отрубить, то в схеме секции:

//можно ещё использовать функцию getFilters
initQueryFilters: function(esq) {
	var filters = this.callParent(arguments);
	//добавляем свои фильтры
	return filters;
}

 

Сериков Асхат Кайратович пишет:

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

Нет, фильтры работают не так. По условиям фильтрации класс EntitySchemaQuery формирует SQL-запрос, который и идёт от сайта в базу. А уже по нему из базы возвращается коллекция записей-результатов.

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

 

Сериков Асхат Кайратович,

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

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

Реализовала такой запрос:

var esqKit = new EntitySchemaQuery(userConnection.EntitySchemaManager, "Kit");

                EntitySchemaQuery kitsCountSubQuery;

                esqKit.AddColumn("Id", AggregationTypeStrict.Count, out kitsCountSubQuery);

                esqKit.Filters.Add(esqKit.CreateFilterWithParameters(FilterComparisonType.Equal, "BTContactPatient",

                    patientId));

                EntityCollection kitsCollection = esqKit.GetEntityCollection(userConnection);

По факту выполнения на стороне sql-сервера формируется корректный sql-запрос и возвращает правильный результат, но я не понимаю, каким образом мне получить результат этого запроса.

Как называется эта колонка и как правильно обратиться к kitsCountSubQuery, чтобы получить результат запроса?

Нравится

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

Алла, нужно запомнить объект-результат AddColumn в переменную, а потом посмотреть её Name. Как тут:

var gridPageEntitySchemaQuery = (EntitySchemaQuery)GridPageEntitySchemaQuery;
var monthColumn = gridPageEntitySchemaQuery.AddColumn(gridPageEntitySchemaQuery.CreateMonthFunction(columnName));
var yearColumn = gridPageEntitySchemaQuery.AddColumn(gridPageEntitySchemaQuery.CreateYearFunction(columnName));
var aggregationValueColumn = gridPageEntitySchemaQuery.AddColumn(
	gridPageEntitySchemaQuery.CreateAggregationFunction(AggregationTypeStrict.Count,
	gridPageEntitySchemaQuery.RootSchema.PrimaryColumn.Name));
EntitySchemaQueryFilterCollection filters = gridPageEntitySchemaQuery.Filters;
filters.Add(gridPageEntitySchemaQuery.CreateFilterWithParameters(FilterComparisonType.IsNotNull,columnName));
var entityCollection = gridPageEntitySchemaQuery.GetEntityCollection(Page.UserConnection);
string dateName = string.Empty;
int month = 0;
foreach (var item in entityCollection) {
	var aggregationValue = item.GetTypedColumnValue&lt;double&gt;(aggregationValueColumn.Name);
	month = item.GetTypedColumnValue&lt;int&gt;(monthColumn.Name);
	dateName =  item.GetTypedColumnValue&lt;string&gt;(yearColumn.Name)+ "-" +(month &lt; 10 ? "0" + month.ToString() : month.ToString());
	series.Add(dateName, aggregationValue);
}

 

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

Спасибо за подсказку - все получилось.

Если интересно, то данная колонка называется просто 'Column'.

А если вторую сделать?

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

Добрый день!

Есть такая задача. 

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

Если зашить эти тексты в справочник или настройку, то там будет сплошной текст и при переносе в поля договора форматирование (абзац) не сформировать. 

Или можно учесть как то абзац при такой схеме?

Спасибо!

Нравится

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

Если мы говорим, о стандартных печатных формах Word, то все форматирование можно настроить в шаблоне печатной формы.

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

Откуда клиент хочет переносить блоки с документов Word ? Тогда лучше на основе этого документа сделать шаблон или штатными средствами или самостоятельно вставить в нужніх местах макроподстановки, открыть на чтение прочитать документ и заменить макроподстановки в шаблоне на нужные значения!

Алла Савельева,

я дам узкий пример. Если в поле Примечание  применить функцию список например, то в печатной форме мы увидим список с какими-левыми символами (скрин прилагаю).

Григорий Чех, я дам узкий пример. Если в поле Примечание  применить функцию список например, то в печатной форме мы увидим список с левыми символами (скрин прилагаю).

Это не «какие-то левые символы», а HTML-теги форматирования текста. Теги для создания списка: li и ol.

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

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

В веб-интерфейсе системы теги отображаются в нужном формате. При переносе в печатную форму текст нужно адаптировать под их формат. Например, вместо настоящего списка имитировать маркеры вставкой символа «•».

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

Нужно при создании лида проверить есть ли уже компания комбинацией БИН и города. Сделал через валидацию, данные читаются все с базы нормально, но проблема в правильном построении callback функции, так как JS пока запускает проверку в базе уже отвечает return в валидацию. PsCode - это БИН поле, City - это города поле

setValidationConfig: function() {
	this.callParent(arguments);
	this.addColumnValidator("PsCode", this.validateCodePlusCity);
},
validateCodePlusCity : function() {
	var invalidMessage = this.get("Resources.Strings.CodePlusCityErrorMessage");
	var code = this.get("PsCode");
	var city = this.get("City");
	if (!code) {
		code = "";
	}
	if (!city) {
		city = "";
	}
	var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "Account"});
	esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
	esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
		"Code", code));
	esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
		"City.Id", city.value));
	esq.getEntityCollection(function(result) {
		if (result.success) {
			invalidMessage = "";
		}
	}, this);
	return {
		invalidMessage: invalidMessage
	};
}

 

Нравится

4 комментария
Лучший ответ
Попробуйте примерно так:

setValidationConfig: function() {
	this.callParent(arguments);
	this.validateCodePlusCity(function(invalidMessage) {
		//Здесь доступно значение invalidMessage
		this.addColumnValidator("PsCode", invalidMessage);
	}, this);
 
},
validateCodePlusCity : function(callback, scope) {
	var invalidMessage = this.get("Resources.Strings.CodePlusCityErrorMessage");
	var code = this.get("PsCode");
	var city = this.get("City");
	if (!code) {
		code = "";
	}
	if (!city) {
		city = "";
	}
	var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "Account"});
	esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
	esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
		"Code", code));
	esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
		"City.Id", city.value));
	esq.getEntityCollection(function(result) {
		if (result.success) {
			invalidMessage = "";
			Ext.callback(callback, scope, [invalidMessage]);
		}
	}, this);
}

 

В esq.getEntityCollection нужно передавать функцию которая обработает результат выборки, в вашем случае скорее всего выдаст сообщение об неуникальности лида! Смотрите асинхронные события JS

Те обработка полученных в запросе данных идет асинхронно!

 

 

 

 

Попробуйте примерно так:

setValidationConfig: function() {
	this.callParent(arguments);
	this.validateCodePlusCity(function(invalidMessage) {
		//Здесь доступно значение invalidMessage
		this.addColumnValidator("PsCode", invalidMessage);
	}, this);
 
},
validateCodePlusCity : function(callback, scope) {
	var invalidMessage = this.get("Resources.Strings.CodePlusCityErrorMessage");
	var code = this.get("PsCode");
	var city = this.get("City");
	if (!code) {
		code = "";
	}
	if (!city) {
		city = "";
	}
	var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "Account"});
	esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
	esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
		"Code", code));
	esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
		"City.Id", city.value));
	esq.getEntityCollection(function(result) {
		if (result.success) {
			invalidMessage = "";
			Ext.callback(callback, scope, [invalidMessage]);
		}
	}, this);
}

 

Если вам нужно валидейтить перед сохранением то имхо лучше использовать asyncValidate Пример ниже callback нужно передать в esq.getEntityCollection.  Если нужно проверять при изменении, можно создать виртуальную колонку и при смене города или БИН менять ее значение в зависимости от результата проверки. А в  setValidationConfig проверять результат проверки уникальности города из виртуальной колонки. Если не получится пишите.

asyncValidate: function(callback, scope) {
    this.callParent([function(response) {
        if (!this.validateResponse(response)) {
            return;
        }
        Terrasoft.chain(
            function(next) {
                this.myValidationMethod(function(response) {
                    if (this.validateResponse(response)) {
                        next();
                    }
                }, this);
            },
            function() {
                callback.call(scope, response);
            },
        this);
    }, this]);
}

 

Спасибо! Отличные ответы, думаю применить теперь еще в других частях кода их.

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

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

 

Каким образом возможно переименовать название поля в Мобильном приложении?

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

Заранее спасибо.

Нравится

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

Точно не помню, но попробуйте посмотреть в Дизайнере системы - Дизайнер мобильной версии, выбираете нужное рабочее пространство, раздел и там смотрите, что можно с полем сделать.

В «Мастере мобильного приложения» можно только выбирать поля, уже существующие в объекте. Соответственно, чтобы переименовать, нужно менять в самом объекте раздела, его в дизайнере (или в переводах, нужно смотреть). Но так поле переименуется везде.

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

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

var TabCandidatesList = tabsCollection.contains("TabCandidatesList") ? tabsCollection.get("TabCandidatesList"):false;
if (!TabCandidatesList) 
     tabsCollection.insert(0, "TabCandidatesList", Terrasoft.TabCandidatesList);
 
var TabConditions = tabsCollection.contains("TabConditions") ? tabsCollection.get("TabConditions"):false;
if (TabConditions) {
	Terrasoft.TabConditions = TabConditions;
	tabsCollection.removeByKey("TabConditions");
}

Как это можно сделать правильно? Хотелось бы при изменении условия вставить вкладку и сразу отобразить ее.

Нравится

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

В твоем случае возможно лучше делать так...

//hide
closeTabs: function() {
	var tabsCollection = this.get("TabsCollection");
	tabsCollection.eachKey(function(tabName, tab) {
		var tabContainerVisibleBinding = tab.get("Name");
		this.set(tabContainerVisibleBinding, false);
		}, this);
	},
//activate
setActiveTab: function(activeTabName) {
	this.closeTabs();
	this.set("ActiveTabName", activeTabName);
	this.set(activeTabName, true);
},

 

Вы не удаляйте вкладку, а скрывайте ее:



 

init: function() {   
 
this.callParent(arguments);
 
var scope = this;
 
require(["jQuery"], function() {
 
  scope.hideTabs();
 
});
 
},
 
 
 
hideTabs: function() {
 
$(document).bind("DOMNodeInserted", function(e) {
 
  if (e.target.id === "Нужный контейнер") {
 
   var tabs = Ext.getElementById("Нужный элемент");
 
   var tab = Ext.get(tabs.children[1]);
 
   if (Условие при котором скрывать) {
 
    tab.setWidth(0);
 
    tab.hide();
 
   }
 
   else {
 
    tab.setWidth("auto");
 
    tab.show();
 
   }
 
  }
 
}.bind(this));
 
}

 

Через DOM работать не получится, т.к. содержимое вкладок подгружается только после нажатия на вкладку... я попробовал работать по схеме описанной в этой теме но видимо есть нюансы работы.  Подскажите, если ли возможно ли назначить активную вкладку из кода используюя tabscollection? 

mcNosferatum,

может быть обновиться до 7.12.4 и использовать это 

http://prntscr.com/kr0luu ?

Попробуй так активировать вкладку

var activeTabName = "GeneralMacrosTab";
this.set("ActiveTabName", activeTabName);
this.set(activeTabName, true);

 

В твоем случае возможно лучше делать так...

//hide
closeTabs: function() {
	var tabsCollection = this.get("TabsCollection");
	tabsCollection.eachKey(function(tabName, tab) {
		var tabContainerVisibleBinding = tab.get("Name");
		this.set(tabContainerVisibleBinding, false);
		}, this);
	},
//activate
setActiveTab: function(activeTabName) {
	this.closeTabs();
	this.set("ActiveTabName", activeTabName);
	this.set(activeTabName, true);
},

 

Литвинко Павел,

Спасибо! Подкорректировал Ваш код и свой и вышло то что нужно)

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

Пользователь нажимает кнопку/действие - идет вызов Исходного кода. Там вылолняется работа и возвращает MemoryStream(это файл ПДФ)

Как теперь сделать чтобы этот файл или скачался или отобразился в новой странице?

Нравится

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

Как то так:

var response = System.Web.HttpContext.Current.Response;
	response.ClearContent();
	response.ContentType = "application/pdf";
	response.AddHeader("Content-Disposition", "inline; filename=" + docName);
	response.AddHeader("Content-Length", docStream.Size);
	response.BinaryWrite((byte[])docStream);
	response.End();

 

Как то так:

var response = System.Web.HttpContext.Current.Response;
	response.ClearContent();
	response.ContentType = "application/pdf";
	response.AddHeader("Content-Disposition", "inline; filename=" + docName);
	response.AddHeader("Content-Length", docStream.Size);
	response.BinaryWrite((byte[])docStream);
	response.End();

 

Григорий Чех,

Благодарю, вот в итоге рабочий код:

var response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "inline; filename=Ведомость расчетов с клиентом.pdf");
response.AddHeader("Content-Length", f.GetLongLength(0).ToString());
response.BinaryWrite(f);
response.End();

f - это тип byte[]

Рад что у вас получилось smiley

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

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

message: Uncaught Terrasoft.InvalidOperationException: SvnSystemException. Can't open file 'C:\Windows\TEMP\1\SBORKI-TS_Developer\Default\Svn\Supervisor\servers'



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

Нравится

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

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

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

Добрый день.

Я могу создать при помощи мастера раздела новую сущность и при этом она будет отображена в интерфейсе bpmonline. А если я создал сущность в конфигураторе, при редактировании своего пакета, как мне эту сущность отобразить в интерфейсе, например, в виде реестра? Существует ли простой способ это сделать? Ведь я не могу в мастере раздела указать уже существующую сущность при создании раздела. Заранее спасибо за ответ. 

Нравится

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