Добрый день!

Пробую при работе с SVN сделать отдельную ветвь разработки и далее откатиться на старый вариант кода.

Есть пакет p1 версии 1.0.1

Создаю новую ветвь 1.0.2 и делаю ее основной.

Но далее я не понимаю как необходимо переключать пакет в BPM Online на новую версию.

Нужно ли создавать новый пакет версии 1.0.2 в самой BPM Online руками, который полностью будет дублировать пакет версии 1.0.1 и располагаться рядом с ним.

Или можно все это сделать в самом SVN несколькими командами.

И после выполнения перехода на новую ветку как проводить откат на старую со старым кодом.

Новая версия пакета должна находиться в другом хранилище или нет?

 

Нравится

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

Смотрите документацию и обсуждения по работе с svn, например тут

Смотрите документацию и обсуждения по работе с svn, например тут

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

 

Я верно понимаю, что все действия идут только на стороне SVN и на стороне BPM Online не потребуется дополнительно перенастраивать пакет?

Александр Кулиш,

Все верно, все действия идут на стороне svn. Вы можете использовать различную стратегию svn, более детально можете ознакомится тут: https://habr.com/ru/post/170589/

Дополнительных действий на стороне bpmonline делать не нужно, Вы просто настраиваете хранилище, и работаете с ним, более детально описано тут: https://academy.terrasoft.ru/documents/technic-sdk/7-13/rabota-s-paketami 

Показать все комментарии
Событийный слой Entity
entity
EntityProccess
7.13_()
service

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

Место событий Entity, событие Saved, для которого был организован событийный подпроцесс. Последний со скриптом и сообщением которое запускает этот скрипт по событию. 

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

Нравится

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

Добавьте еще подписку на событие, перед сохранением.

Так же делаете подписку, скрипт.

В параметрах создайте нужные переменные нужных типов.

После чего в самом скрипте "перед сохранением", делайте так:

ContactOld = Entity.GetTypedOldColumnValue<Guid>("Contact");

Затем, в вашем скрипте "После сохранения" делайте сверку

if (ContactOld != Entity.GetTypedColumnValue<Guid>("Contact") { // }

Добавьте еще подписку на событие, перед сохранением.

Так же делаете подписку, скрипт.

В параметрах создайте нужные переменные нужных типов.

После чего в самом скрипте "перед сохранением", делайте так:

ContactOld = Entity.GetTypedOldColumnValue<Guid>("Contact");

Затем, в вашем скрипте "После сохранения" делайте сверку

if (ContactOld != Entity.GetTypedColumnValue<Guid>("Contact") { // }

Это можно сделать только в событийном процессе объекте перед сохранением записи

Entity.GetColumnOldValue("Name")

или

Entity.GetTypedOldColumnValue<String>("Name");

 

Добрый день!

На вход элемента скрипта обработки сохранения подается переменная ProcessExecutingContext context (https://monosnap.com/file/TP10NeOGRBkG4zXPFKxrVZM8Tvj4I6).

В ней есть public object ThrowEventArgs { get; set; }, которая приводится к объекту EntityAfterEventArgs. А в этом объекте уже есть массив измененных колонок: public EntityColumnValueCollection ModifiedColumnValues { get; set; }

Еще проще проверить что столбец изменен

var flag = Entity.GetChangedColumnValues().Any(col => col.Name == "Date");

Всем спасибо!

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

Добрый день, коллеги!

В продолжаю изучение бизнес-процессов. Кейс следующий:

В элементе "Читать данные" в разделе "Значение каких колонок вычитать?" вывожу колонку Название (string). Затем в бизнес-сценарии хочу ее передать и проанализировать. Каким образом передаются эти значения?

Спасибо!

Нравится

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

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

string myString = Get&lt;string&gt;("myParameter");

 

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

string myString = Get&lt;string&gt;("myParameter");

 

Alex Zaslavsky,

Спасибо, попробую!

Получить и обработать коллекцию в интрпритируемом БП можно примерно так:  

var entities = Get&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt; ("ReadDataUserTask1.ResultCompositeObjectList");
var result = "";
foreach(var entity in entities) 
{
   var cityName = entity.GetTypedColumnValue&lt;string&gt;("Name");
}
Если нужна только одна прочитаная запись то получить ее можно так:
var entity = entities.FirstOrDefault();
 
Показать все комментарии

Добрый день!



Вопрос следующего характера:

Необходимо изменить номера обращений - переделать поле текстовое в числовое. Есть пример https://community.terrasoft.ru/articles/sortirovka-po-nomeru-dogovora-d… но там выводится новая колонка, но моя задача - изменить текущую.



1) Что стоит предусмотреть и что может повлиять на работу? (сейчас создаются новые обращения формата "только цифры")

2) Если в это поле будет писаться текст (случайно попадет) - что изменится?

3) Что станет с БП, которые берут значение этого поля как текст?

Нравится

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

Быстров Сергей,

Как то так попробуй (код набросал на глазок, те сырой нужно  отлаживать)

initQuerySorting: function(esq) {
	var columnName = "Number";
	if (esq.columns.contains(columnName)) {
		//var numColumn = esq.addColumn(columnName);
		var numColumn = esq.columns[columnName];
		if (numColumn.orderPosition &amp;&amp; numColumn.orderPosition &gt; 0) {
			var numNewColumn = esq.addColumn("NewNumberIntegere");
			numNewColumn.orderDirection = numColumn.orderDirection;
			numNewColumn.orderPosition = numColumn.orderPosition;
			delete numColumn.orderDirection;
			delete numColumn.orderPosition;
		} else {
			this.callParent(arguments);
		}
}
},

 

А почему нельзя добавить новую колонку, спрятав при необходимости старую, при этом все базовая функциональность и ваши наработки работающие с номерами останется работоспособной

1) трудно сказать  нужно тестировать полностью весь блок работы с обращениями выискивая блох

2) в число текст не впихнуть будет ошибка при сохранении

3) зависит от того как именно обрабатывается строка в БП

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

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

Быстров Сергей,

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

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

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

Быстров Сергей,

Есть еще костыльный вариант установить шаблон маски в SP{0:00000000} тогда номера будут формироватся в виде SP000000001,  SP000000002 и тд что позволит сортировать по текстовому полю номер, возможно вам это подойдет если пользователи не будут ругаться на лидирующие нули.

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

А вот на это ругается первая линия, потому что "лишние цифры - это плохо". Поэтому сразу откинули такой вариант. Может можно как-то переопределить фильтр: когда мы пытаемся фильтровать по номеру, на самом деле фильтр делается по другому полю "UsrNumber"?

Быстров Сергей,

Фильтр не трогать, а можно попытатся переопределить сортировку, те при попытке сортировать по номеру отсортировать по новому числовому полю номер

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

А провернуть такое можно, если в реестре не выведена эта колонка? Просто еще ни разу не делал подобного. Если есть какие-то примеры - буду рад.

Быстров Сергей,

Как то так попробуй (код набросал на глазок, те сырой нужно  отлаживать)

initQuerySorting: function(esq) {
	var columnName = "Number";
	if (esq.columns.contains(columnName)) {
		//var numColumn = esq.addColumn(columnName);
		var numColumn = esq.columns[columnName];
		if (numColumn.orderPosition &amp;&amp; numColumn.orderPosition &gt; 0) {
			var numNewColumn = esq.addColumn("NewNumberIntegere");
			numNewColumn.orderDirection = numColumn.orderDirection;
			numNewColumn.orderPosition = numColumn.orderPosition;
			delete numColumn.orderDirection;
			delete numColumn.orderPosition;
		} else {
			this.callParent(arguments);
		}
}
},

 

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

Спасибо за помощь, получилось вот так:

initQuerySorting: function(esq) {
	this.callParent(arguments);
	var columnName = "Number";
	if (esq.columns.contains(columnName)) {
	var numColumn = esq.columns.collection.get(columnName);
		if (numColumn.orderPosition &amp;&amp; numColumn.orderPosition === 1) {
			var numNewColumn = esq.columns.collection.get("UsrNumber");
			numNewColumn.orderDirection = numColumn.orderDirection;
			numNewColumn.orderPosition = 0;
			delete numColumn.orderPosition;
		}
	}
},
getGridDataColumns: function() {
	return {
		"UsrVIPobr": {path: "UsrVIPobr"},
		"UsrNumber": {path: "UsrNumber"}
	};
},

 

Показать все комментарии
EntitySchemaQuery
ServiceHelper
7.10
service

Добрый день коллеги.

Столкнулся со странной ситуацией. Обратился к ТС, но все же решил и тут задать свой вопрос:

При реализации очередной кастомизации необходимо было выполнить запрос EntitySchemaQuery:

    

    var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager.GetInstanceByName("ServiceEngineer"));

    var colId = esq.AddColumn(esq.CreateAggregationFunction(AggregationTypeStrict.Count, "Id"));

    var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "ServiceItem", serviseId);

    esq.Filters.Add(esqFilter);

    result = esq.GetSelectQuery(UserConnection).GetSqlText();

    return result;

Реализовывал с использованием ServiceHelper, где для анализа данных реализовал два метода: GET и POST.

Странность заключается в том, что исходный код у данных методов одинаков, а результат разный (см. аттач GET.png и POST.png)

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

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

Нравится

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

Вероятно, дело не в GET и POST, а в том, что второй раз запускается под пользователем, у которого нет прав на таблицу ServiceEngineer. См. тут или тут.

Показать все комментарии
Обращения
7.13_()
service

Ситуация по шагам: 

1. Клиент пишет обращение 

2. Ему приходит оповещение (Ваше обращение зарегистрировано т.д.) 

3. Клиент отвечает на это оповещение что-либо. 

4. В системе создается новое обращение 

5. Клиенту приходит еще одно оповещение соответственно. 

 

Разворачивал демостенд, насколько понимаю это является стандартной логикой BPM. 

Вопрос:

Можно ли избежать такой ситуации? Как сделать так, что бы при ответе на оповещение не создавалась новое обращение? 

Нравится

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

Новые письма привязываются к существующим инцидентам, если в их тексте есть упоминания номера, например №SR-12345.Значит, нужно в автоматическом шаблоне или в ручном ответе указывать номер в таком формате. Тогда при ответе будет не создаваться новое, а переоткрываться старое. Формат задаётся в системной настройке «Маска номера обращения». 

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

Добрый день!

Имеется следующий кейс: закрытие подчиненных обращений после закрытия родительского.

Возможно ли реализовать данный кейс посредством бизнес-процессов?

Нравится

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

Возможно

стартовый сигнал изменение состояния обращения на закрыто (отменено/огтклонено), дальше меняете состояния у всех не закрытых обращений у которых Id из стартового сигнала родитель!

Возможно

стартовый сигнал изменение состояния обращения на закрыто (отменено/огтклонено), дальше меняете состояния у всех не закрытых обращений у которых Id из стартового сигнала родитель!

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

Благодарю! Сработало.

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

Добрый день. Версия 7.12.

Подскажите, в чём может быть причина возникновения такой ошибки при загрузке деталей:

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

Возникает при открытии вкладки с деталями, страница на этом перестаёт грузиться и зависает.

Нравится

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

Уточните, после каких изменений начала возникать описанная проблема?

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

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

Добрый вечер!

После переустановки ОС на Win 10, в CRM не работает часть функционала.

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

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

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

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

3. При использовании функции «Глобальный поиск», нет возможности перейти ни к одному из найденных пунктов. Система выдает предупреждение.

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

 

4. При попытке открыть меню Файл-Настройки-Системные настройки, CRM выдает ошибку .

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

 

Прочитала на community (https://community.terrasoft.ru/questions/obnovlenia-win10-i-terrasoft-34) , что в версии 3.3.4 можно удалить обновление KB4074588, но к сожалению, такой технической возможности у нас в компании нет. Подскажите, пожалуйста, как можно решить эти проблемы? Спасибо!

Нравится

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

Под Windows 10 не работают полноценно ни 3.3.2, ни 3.4.0. Нужно обновляться с 3.3.2 на 3.4.1: скачивать новые файлы программы, менять номер версии в базе в tbl_DatabaseInfo и покупать заново лицензии. Либо же продолжать использовать предыдущие версии Windows.

И, заодно, если у кого-то 3.3.1, там обновление, помимо упомянутого, требует дополнительных шагов.

Зверев Александр, Александр, спасибо за ответ! К сожалению, обновиться до версии 3.4.1 нет возможности, по политике компании.

Всё дело в том, что на первых ПК с обновленной ОС, CRM работал корректно, как и на Win 7.

Но на ПК, которые ставим сейчас, CRM работает не корректно. Сравнили версии ОС, они разные. Обратились сейчас в наш тех.отдел. Чтобы они попытались понять в чем разница, между версиями на ОС Win 10. Ждем от них ответа.

Так в том и дело, что Win10 перестала нормально работать с 3.3.2 и 3.4.0 начиная с одного из её обновлений около года назад.

Показать все комментарии
7.13_()
service

Добрый день!



Столкнулись со следующей задачей:

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



Поэтому появляется три вопроса:

1) как осуществить функционал вставки из буфера? Например: находясь в поле "Решение" нажимается вставка скриншота из буфера и в детали "Файлы и ссылки" этого обращения появляется файл с названием "Решение_Название файла"

2) вставка документа (например pdf) путем перетаскивания его на поле "Решение" и чтобы он появлялся в детали "Файлы и ссылки" этого обращения появляется файл с названием "Решение_Название файла"

3) как добавить в шаблон, который отправляется автоматически, эти самые файлы? С использованием макросов invoke?



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

Нравится

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

По размеру, есть системная настройка «Максимальный размер загружаемого файла» (MaxFileSize). По умолчанию там 10 Мб, можно менять.

По шаблону со вложением, см. приложение.

По остальному, в теории, такое возможно. Например, на детали файлов в любом разделе есть место для перетаскивания файла. См. в FileDetailV2 логику, связанную с DragAndDropContainer:

onFileSelect: function(files) {
	if (files.length &lt;= 0) {
		return;
	}
	const config = this.getUploadConfig(files);
	const isNewRecord = this.getIsNewRecord();
	this.set("FileUploadConfig", config);
	if (isNewRecord) {
		const args = {
isSilent: true,
messageTags: [this.sandbox.id]
		};
		this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
	} else {
		this.upload(config);
	}
},
 
 
/**
 * Uploads files using FileAPI.
 * @private
 * @param {Object} config File upload configuration.
 * @param {Function} callback Callback.
 */
upload: function(config, callback) {
	this.Terrasoft.ConfigurationFileApi.upload(config, callback);
},
 
 
onUpload: function() {
	this.showBodyMask();
},
 
initDropzoneEvents: function() {
	const dropZone = document.getElementById("DragAndDropContainer");
	if (!dropZone) {
		return;
	}
	if (this.Terrasoft.Features.getIsEnabled("CheckMasterRecordEditRights") &amp;&amp;
!this.get("CanEditMasterRecord")) {
		return;
	}
	this.Terrasoft.ConfigurationFileApi.initDropzoneEvents(dropZone, function(over) {
		if (over) {
dropZone.classList.add("dropzone-hover");
		} else {
dropZone.classList.remove("dropzone-hover");
		}
	}, function(files) {
		this.onFileSelect(files);
	}.bind(this));
},
 
onRender: function() {
	this.callParent(arguments);
	this.initDropzoneEvents();
...

 

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