Добрый день.

В связи с нововведениями этого лета на community и на портале самообслуживания прошу ответить на ряд вопросов:

1. Community:

Раньше на community можно было беспрепятственно скачать дистрибутив любой версии BPMOnline для ведения разработки локально. Как сейчас получить дистрибутив нужной версии?

2. Портал самообслуживания: 

Зашел на портал по ссылке: http://support.bpmonline.com

Получаю сообщение: 

Информация
Для работы с обращениями в службу поддержки и вашему менеджеру перейдите на новый портал. Работа с обращениями по проектной функциональности продолжается на данном портале

Захожу по новой ссылке: https://success.bpmonline.com. Пытаюсь авторизоваться c учетными данными старого портала. В итоге ошибка "Ваша учетная запись неактивна. Системный администратор может активировать учетную запись на странице пользователя". Можно ли активировать учетную запись на новом портале?

Нравится

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

Дистрибутивы теперь хранятся на в базе знаний новом портале success. Данные для доступа к нему стоит запросить у вашего менеджера. Старые логин и пароль не подходят.

Показать все комментарии
Мобильное приложение
глобальный поиск
7.10
sales

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

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

Нравится

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

Здравствуйте, Павел! 

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

Еще одна альтернатива - при идеальной ситуации, когда у каждого контрагента есть хоть 1 контакт, можно попробовать переписать поиск, чтобы в разделе контакты он выбирал не только по полю ФИО но еще и по полю Контрагент.

Здравствуйте, Илья, спасибо за ответ.

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

Terrasoft.sdk.GridPage.setSearchColumns("Contact", ["Name", "Account"]);

 

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

Добрый день!





Решаю следующую задачу:

 

Необходимо отправлять e-mail уведомление раз в неделю в пятницу руководителю. E-mail должен содержать список лидов, по которым не было ни одной активности в течении 30 .

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

Возможно вы сталкивались с аналогичной задачей.

 

Нравится

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

CRON триггер (простого будет достаточно). В принципе и в академии есть и здесь если поиском посмотреть. Логика такая - запускаете процесс один раз руками. Он планирует следующий запуск сам. Потом выбираете нужные лиды, в цикле наполняете текст сообщения [Текст строки] + "<br>", потом это вставляете в тело письма. Лучше всего сделать элементом "скрипт": esq запросом выбрать по параметрам лиды, сложить текст и присвоить значение параметру процесса. Пользовательскими (административными) средствами решить нельзя (пока).

Спасибо за ответы, Дмитрий! Буду пробовать реализовать)

Добрый день!

В ближайшем релизе bpm’online появятся пользовательские инструменты для настройки запуска процессов по расписанию. В дизайнере бизнес процесс появиться новый элемент «Стартовый таймер», с помощью этого элемента можно будет указать любую периодичность запуска бизнес-процесса

https://academy.terrasoft.ru/documents/upcoming-releases#8

Показать все комментарии
showConfirmationDialog
LocalizableString
Caption
7.10

Подскажите, не получается для showConfirmationDialog сделать LocalizableString.

Кнопка попросту не отображается, до тех пор пока в caption не введу конкретную строку.

var ButtonDoItCfg= {
"className": "Terrasoft.Button",
"returnCode": "ButtonDoIt",
"style": "green",
"caption": { "bindTo": "Resources.Strings.ButtonDoItCaption" }
};
var cfg = {
style: Terrasoft.MessageBoxStyles.BLUE
};
this.showConfirmationDialog( cs1 + " " + cs2,
function getSelectedButton(returnCode) {
if (returnCode === Terrasoft.MessageBoxButtons.YES.returnCode) {
var args = {
sysProcessName: "ButtonDoItProcessCode",
parameters: {
BPcs1: csID1,
BPcs2: csID2
}
};
ProcessModuleUtilities.executeProcess(args);
}
}, ["yes", "no", ButtonDoItCfg], cfg);

 

Нравится

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

1) Возможно вы зыбыли в самой схеме пробросить объект Resources для зависимости

 

define("LeadPageV2", ["LeadPageV2Resources"], function(resources) {
...

т.е. в зависимостях необходимо добавить {Имя схемы}Resources

и на "вход" результирующей функции соответствующий аргумент, в итоге получите а контексте карточки объект вот такой

в Вашем коде соответственно используйте не текстовую мнемонику 

"Resources.Strings.ButtonDoItCaption"

а прямо передавайте необходимое свойство объекта.

PS: я сомневаюсь что в жизненном цикле карточки у Вас происходит изменение локализуемых строк...

Показать все комментарии
бизнес-правила
процесс
7.10
studio

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

Нравится

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

имеется в виду бизнес-процесс ?

Севостьянов Илья Сергеевич,

Да.

я не уверен, что такая возможность имеется, именно в виде "изменить бизнес-правило", но можно создать бизнес-правила выполнение которых зависит от значения атрибута модели, и например "скрытое поле" в целевом объекте, в бизнес-процессе устанавливать значение в это поле, а в целевой схеме предусмотреть логику (н/п в onEntityInitialized) которая опираясь на значение вышеуказанного поля будет устанавливать значение в атрибут модели.

Итоговый результат, ИМХО - это тот кейс, который вы хотите реализовать, насколько я понял.

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

пользователи спрашивают как копировать строки деталей.

из идей как это сделать.

Привязать действие на кнопку три точки в детали

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

 

но как сделать так чтобы деталь обновилась после копирования.

Нравится

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

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

Сделайте на детали редактируемый реестр - там уже есть кнопка, которая позволяет скопировать запись. Также в базовой версии на "трех точках" (на действиях детали) уже есть кнопка копирования (см. деталь "Адреса" на странице раздела "Контакты").

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

Если еще актуально или необходимо для другого кейса - у BasePageV2 есть методы loadDetail и reloadDetail. Также отмечу, что "обновить" деталь можно изменив направление или колонку сортировки.

reloadDetail - идеальный кандидат.

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

Добрый день!





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

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

Нравится

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

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

При нажатии на "Добавить" возможны два варианта:

  • Открывается миникарточка контакта
  • Открывается страница редактирования новой записи контакта (в том же окне)

Предполагаю, что имеется ввиду именно миникарточка. Для базовых разделов системы уже предусмотрена миникарточка. Ее появление регласметируется системной настройкой "Использовать миникарточку добавления [#записи#]", где [#запись#] - это название сущности, например, контакта, контрагента, активности.

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

https://academy.terrasoft.ru/documents/technic-sdk/7-10/sozdanie-mini-k…

Здравствуйте, открытие карточки добавления записи детали по "+" невозможно в новой вкладке т.к. требует "истории" и "контекста" что невозможно передать на текущий момент через url. А открытие в новой вкладке может быть реализовано только лишь через url.

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

Стоит следующая задача: если в карточке контакта изменилось текущее значение поля [Статус] на 'Reject', задать пользователю вопрос вида: "Вы, действительно, хотите установить 'Reject' статус", если пользователь отвечает да, тогда должен запускаться БП, который изменит статусы других, связанных объектов, если нет, тогда статус должен возвращаться в предыдущее состояние.

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

Для поля [Статус] создано dependencies, в котором реализован вызов следующего метода:

               var status = this.get("BTContactStatus");

                if (this.Ext.isEmpty(status)) {

                    return;

                }

                if (status.value === "f7ade63f-213d-4daa-a73d-75684c4bd689") {

                    var message = "Do you want set 'Reject' status?";

                    this.showConfirmationDialog(this.Ext.String.format(message, 1), function (result5) {

                        if (result5 === Terrasoft.MessageBoxButtons.NO.returnCode) {

                             var entity = Ext.create("Terrasoft.EntitySchemaQuery", {

                                rootSchemaName: "Contact"

                            });

                            entity.addColumn("BTContactStatus");

                            entity.filters.addItem(entity.createColumnFilterWithParameter(

                            this.Terrasoft.ComparisonType.EQUAL, "Id", this.get("Id")));

                            entity.getEntityCollection(function(result) {

                                if (result.success) {

                                    if(result.collection.getCount() < 1) {

                                        this.set("BTContactStatus", null);

                                        return;

                                    }

                                    this.set("BTContactStatus", result.collection.getByIndex(0).get("BTContactStatus"));

                                }

                            }, this);

                        }

                    }, ["yes", "no"]);

                }

В методе описан сценарий, когда пользователь на вопрос отвечает 'Нет', а если пользователь на вопрос отвечает 'Да', в методе ничего не происходит, но в системе реализован процесс, который запускается по сигналу изменения статуса у контакта на 'Reject'.

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

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

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

И насколько целесообразно в данной задаче использовать валидацию для поля или есть другие способы решения данной задачи?

 

 

 

Нравится

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

Для контроля изменения в поле - необходимо установить на него dependencies (свойство конфигурационного объекта атрибута)

https://academy.terrasoft.ru/documents/technic-sdk/7-10/atributy-svoystvo-attributes

н/п установим метод обработчик для поля "Contact"

attributes:{
...
"Contact": {
	dependencies: [
		{
			columns: ["Contact"],
			methodName: "ContactChangeHandler"
		}
	]
}
...
},

вашу логику вынести в метод обработчик

в котором задайте интересующий вас вопрос пользователю

Terrasoft.utils.showMessage({
	caption: "Ваше сообщение пользователю",
	//набор используемых кнопок из списка стандартных для диалоговых окон
	buttons: ["yes", "no"],
	//метод-обработчик выполненных пользователем действий
	handler: function(code) {
		//если пользователь нажал "Да"
		if (code === "yes") {
			//ToDo
		//если пользователь нажал "Нет"
		//проверять необходимо явно, т.к. окно можно и просто закрыть
		} else if (code === "no") {
			//ToDo
		//логика "по умолчанию"
		} else {
			//ToDo
		}
	},
	defaultButton: 0,
	//контекст в котором будет вызвана функция обработчик handler
	scope: this
});



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

н/п создав специальный атрибут

attributes:{
...
"rollbackByContactChangeFlag": {
	"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
	"dataValueType": Terrasoft.DataValueType.BOOLEAN,
	"value": false
}
...
},

в начале же вашего метода-обработчика изменения ориентируйтесь на его значение. 

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

Добрый день! Возник вопрос по воронкам - можно ли в bpm создать воронку, которая бы показывала продвижение сделки от лида (переход по всем стадиям), затем по стадиям продажи, по состояниям заказа и вплоть до оплаченного счета (чтобы все данные отображались в одной воронке)?

Нравится

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

Думаю, что с помощью стандартных средств реализовать такую задачу не получится. Как минимум, для её реализации нужно сделать специальное представление, которое соберет информацию по всем сущностям. Вьюху можно реализовать с помощью конструкции union в sql.

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

Показать все комментарии
API
files
7.10
marketing

Здравствуйте. Как можно загрузить файл через API (odata) и прикрепить его к определенному контакту/лиду/заданию/звонку и тп? Пробовал через модели odata, но выдавало ошибку, что такая модель еще не доступна. Скорее всего, я что-то не так делал. Может кто-то сталкивался с таким вопросом. Буду рад любой помощи. Спасибо.

Нравится

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

как по мне очень похоже на вот это: https://community.terrasoft.ru/questions/realizacia-peredaci-pdf-dokume…;

Там конечно про pdf, но описанные действия вроде подходят для всех типов файлов. 

Спасибо. Сейчас делаю так:

1. POST запрос с привязкой к контакту и задаю название файла.

2. PUT запрос передаю файл.

Но на 2 этапе возникает проблема. Когда я передаю файл через POSTMAN и позже его скачиваю из CRM. Файл не открывается должным образом. Открыв файл через notepad++ и забрав такие заголовки

----------------------------606529554623297003963904
Content-Disposition: form-data; name=""; filename="bcr_scren.png"
Content-Type: image/png

картинка (в данном случае) открывается нормально.

При этом я создал PHP скрипт у себя на сервере для загрузки файлов и передаю точно такие-же параметры и заголовки как и в CRM. Файл загружается без проблем.

Скрин из POSTMANa:

Заголовок запроса такой: Content-Type: multipart/form-data.

Вы используете обычный EntityDataService. Но, судя по ссылке, есть отдельный FileApiService именно для работы с файлами. Примеры работы с ним можно увидеть в самой системе на детали файлов, а уходящие из браузера запросы на сервер посмотреть в Fiddler.

См. примеры тут.

Посмотрите, как работает с файлами через этот сервис интерфейс системы. Готовых примеров решения такой задачи на PHP нет, поскольку bpm'online использует JS на клиенте и С#  на сервере. Следовательно, найти примеры на этих языках шансов намного больше.

Запустил Fiddler, добавил файл на деталь, POST-запросы к сервисам записались нормально. Сначала собственно добавление:

/0/rest/FileApiService/Upload?fileapi15301911041375&totalFileLength=13036&fileId=935b6ecb-3509-4c8a-bc7e-03ab0661da24&mimeType=&columnName=Data&fileName=myfilename.rar&parentColumnName=Contact&parentColumnValue=c4ed336c-3e9b-40fe-8b82-5632476472b4&entitySchemaName=ContactFile

В качестве содержимого запроса — сам файл.

Потом запрос на выборку :

/0/DataService/json/SyncReply/SelectQuery

С содержимым:

{"rootSchemaName":"ContactFile","operationType":0,"filters":{"items":{"primaryColumnFilter":{"filterType":1,"comparisonType":3,"isEnabled":true,"trimDateTimeParameterToDate":false,"leftExpression":{"expressionType":1,"functionType":1,"macrosType":34},"rightExpression":{"expressionType":2,"parameter":{"dataValueType":0,"value":"935b6ecb-3509-4c8a-bc7e-03ab0661da24"}}}},"logicalOperation":0,"isEnabled":true,"filterType":6},"columns":{"items":{"Id":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":0,"columnPath":"Id"}},"Name":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":0,"columnPath":"Name"}},"Type":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":0,"columnPath":"Type"}},"Version":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":0,"columnPath":"Version"}},"CreatedBy":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":0,"columnPath":"CreatedBy"}},"Notes":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":0,"columnPath":"Notes"}},"EntryPointsCount":{"caption":"","orderDirection":0,"orderPosition":-1,"isVisible":true,"expression":{"expressionType":3,"aggregationType":1,"columnPath":"[EntryPoint:EntityId].Id","subFilters":{"items":{"c11b1561-6443-42de-8768-f6db6d774678":{"filterType":1,"comparisonType":3,"isEnabled":true,"trimDateTimeParameterToDate":false,"leftExpression":{"expressionType":0,"columnPath":"IsActive"},"rightExpression":{"expressionType":2,"parameter":{"dataValueType":1,"value":true}}}},"logicalOperation":0,"isEnabled":true,"filterType":6}}}}},"isDistinct":false,"rowCount":-1,"rowsOffset":-1,"isPageable":false,"allColumns":false,"useLocalization":true,"useRecordDeactivation":false,"serverESQCacheParameters":{"cacheLevel":0,"cacheGroup":"","cacheItemName":""},"isHierarchical":false}

 

 

 

 

 

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

Так и делаю, шлю POST на URL

https://bookimed.bpmonline.com/0/rest/FileApiService/Upload?fileapi15301911041375&totalFileLength=".filesize($localfile)."&fileId=" . $fileId . "&mimeType=&columnName=Data&fileName=test.png&parentColumnName=Order&parentColumnValue=f106146d-817a-4359-a7a8-a2386c14c7bb&entitySchemaName=OrderFile

А в ответ получаю The server encountered an error processing the request. The exception message is 'Невозможно определить размер файла'

Хотя я передаю totalFileLength в строке запроса - эту ошибку тоже вспоминали тут https://community.terrasoft.ru/questions/fileapiservice-zagruzka-dokume… и но не объяснили как побороть

Видимо, размер реально оказывается не тот или не в том формате. Сравните в Fiddler Ваш и автоматический запросы.

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

 Разобрался! Нужно в хэдере еще указывать

'Content-Range: bytes 0-'.(filesize(realpath($localfile))-1).'/'.filesize(realpath($localfile)),

АПИ уже работает и отвечает ОК

Спасибо за важное уточнение.

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