Добрый день коллеги! Возникла необходимость немного расширить функционал генерации лидов через "Лендинг страницы". Подскажите пожалуйста, можно ли получить не минимизированную версию js скрипта create-object.js - для того чтобы посмотреть как он работает/возможно внести некоторые изменения на моменте инициализации объекта "landing"
(загружается на страницу-лендинг с https://webtracking-v01.bpmonline.com/JS/create-object.js)

Нравится

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

Поправка, не увидел что в мин версии файла длинные названия переменных и функций - так что его можно легко вернуть в нормальный вид. Вопрос отпадает :smile:

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

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

Версия 7.9 sales.

На странице есть кнопка Отмена (см. скриншот). Необходимо добавить событие на эту кнопку. Событие связано с изменениями данных на странице и пересчётами параметров, но дело не в нём.

onDiscardChangesClick: function(){
        this.callParent(arguments);
        console.log("Событие");
}

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

Соответственно, вопрос - как правильно сделать? Какая функция должна быть переопределена, или быть может, есть sandbox-сообщение, на которое можно подписаться и вызывать через него требуемое событие?

Нравится

3 комментария
onDiscardChangesClick: function() {
	if (this.isNew) {
		this.sandbox.publish("BackHistoryState");
		return;
	}
	this.set("IsEntityInitialized", false);
	this.loadEntity(this.getPrimaryColumnValue(), function() {
		this.updateButtonsVisibility(false, {
			force: true
		});
		this.initMultiLookup();
		this.set("IsEntityInitialized", true);
		this.discardDetailChange();
		this.updatePageHeaderCaption();
	}, this);
	if (this.get("ForceUpdate")) {
		this.set("ForceUpdate", false);
	}
},

Кажется мне, что в сферическом вакууме перезагрузка entity выглядит как-то так:

this.loadEntity(recordId, callback, scope)

Ну и поскольку она асинхронна, попробуйте добавить console.log после, допустим, this.updatePageHeaderCaption()

Здравствуйте, Денис.

Предыдущий комментатор верно подметил. Для замещения, Вам необходимо переписать метод onDiscardChangesClick целиком (вызова this.callParent(arguments) будет недостаточно) и добавить свой код в коллбэк функцию из метода loadEntity.

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

Илья, Данила - спасибо!

Вроде как задача решена.

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

Добрый день.

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

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

С уважением,
Александр

Нравится

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

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

Данная задача может быть реализована бизнес-процессом. Вызвать созданнный бизнес-процесс вы сможете, используя элемент "Подпроцесс".

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

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

Тип потребности=="Программное обеспечение" в дизайнере отображены вот эти стадии:
"Квалификация->Презентация->Коммерческое предложение..."
https://yadi.sk/i/U7CRVIfp38ChcL

Тип потребности!="Программное обеспечение" в дизайнере - эти стадии:
"Анализ потребностей->Подготовка предложения->Отправка опытных образцов..."
https://yadi.sk/i/1y-_PWog38ChZf

С уважением,
Александр

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

Вы можете настроить доступность перехода в справочнике "Доступные переходы по стадиям продажи".
Таким образом вы решите проблему перехода между стадиями.

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

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

Исчезает значение локализируемой строки.

Не удается выполнить копирование локализируемой строки ScriptTemplate из BaseGeneratedWebFormPageV2 в мою созданную. При попытке записи значения и сохранения, после сохранение значение этой строки становится пустым.

Кто с таким встречался?

Нравится

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

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

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

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

Добрый день!

Не смог найти на форуме информации по изменению размера шрифта для версий 7.x
Есть возможность изменять размер шрифта на карточке и в реестре?

С уважением,
Дмитрий

Нравится

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

Добрый день, Дмитрий.

Стили, отвечающие за шрифт, а также часть стилей, отвечающих за размер шрифта, Вы можете найти в схеме BaseFontsCSS. Основная же часть стилей расположена в файле all-combined.css в папке самого приложения.

Простейшим же способом будет добавить в конфигурации схемы содержащие пользовательские стили, а затем добавить их в зависимости к замещающим схемам к которым их необходимо применить (к примеру, BasePageV2 или BaseSectionV2).

Добавление пользовательских css стилей обсуждалось в следующей теме:

http://www.community.terrasoft.ru/forum/topic/16386

Также убедитесь, что добавленные Вами стили имеют приоритет над стандартными:

https://developer.mozilla.org/ru/docs/Web/CSS/Specificity

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

Добрый день

В Е-мейл активности при нажатии на кнопку нужно добавить в HtmlBody этой Е-мейл-активности имя контакта текущего пользователя. Пишу скрипт:

string html = Page.DataSource.ActiveRow.GetTypedColumnValue("HtmlBody");

Guid contactId = UserConnection.CurrentUser.ContactId; //id контакта текущего пользователя
string contactName = UserConnection.CurrentUser.ContactName; //имя контакта текущего пользователя

string str = String.Concat(contactName, html);

var defValuesId = Entity.GetTypedColumnValue("ActivityId");
var defValues = ? // что здесь нужно написать?

defValues.Add("HtmlBody", str);

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

Нравится

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

Что именно написать в коде, зависит от того, что Вы хотите получить.
Если вбить в поиск по конфигурации «var defValues =», получим:

var defValues = new Dictionary <string, object>();

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

А если я хочу заменить содержимое HtmlBody в открытом док-те нажатием на опред.кнопку, правильно ли я использую var defValues ? Заранее спасибо.

Получилось и работает:

string html = Page.DataSource.ActiveRow.GetTypedColumnValue("HtmlBody");

Guid contactId = UserConnection.CurrentUser.ContactId; //id контакта текущего пользователя
string contactName = UserConnection.CurrentUser.ContactName; //имя контакта текущего пользователя

string str = String.Concat(contactName, html);

Page.DataSource.ActiveRow.SetColumnValue("HtmlBody", str);

return true;

Если поставить теги
, то в BPMOnline вид текста в е-мейл активности отображается с учетом переносов на новую строчку. Но, отправив на эл.адрес эту е-мейл, вижу: в Qutlook в полученном электронном письме текст слился в одну строчку. Подскажите, пожалуйста, как можно этого избежать? Заранее спасибо

Полный текст:
string html = Page.DataSource.ActiveRow.GetTypedColumnValue("HtmlBody");

Guid contactId = UserConnection.CurrentUser.ContactId; //id контакта текущего пользователя
string contactName = UserConnection.CurrentUser.ContactName; //имя контакта текущего пользователя
string contactmail = Terrasoft.Configuration.CommonUtilities.GetEntityTypedColumnValue(UserConnection, "Contact", "Email", contactId);
string contactdol = Terrasoft.Configuration.CommonUtilities.GetEntityTypedColumnValue(UserConnection, "Contact", "JobTitle", contactId);
string contactphone = Terrasoft.Configuration.CommonUtilities.GetEntityTypedColumnValue(UserConnection, "Contact", "Phone", contactId);
string contactMobilePhone = Terrasoft.Configuration.CommonUtilities.GetEntityTypedColumnValue(UserConnection, "Contact", "MobilePhone", contactId);

string s6 = "Добрый день"+"


С уважением,
"+ contactName + "
" + contactdol + "
Департамент информационных технологий
АО «ДКС»"+ "

Tel :"+ contactphone + ", " + contactMobilePhone + "
e-mail :"+ contactmail +" , www.dkc.ru";

string str = String.Concat(s6, html);

Page.DataSource.ActiveRow.SetColumnValue("HtmlBody", str);

Погодите...
Если html содержит картинку, то текст вываливается в одну строчку, а если html нет картинок, то текст прописывается как надо. Подскажите, пжста, есть ли решение, как уйти от этой проблемы? Заранее спасибо

Погодите...
Если html содержит картинку, то текст вываливается в одну строчку, а если html нет картинок, то текст прописывается как надо. Подскажите, пжста, есть ли решение, как уйти от этой проблемы? Заранее спасибо

Перенос строк в письме формата HTML делается так же, как и в других HTML-страницах: при помощи тега

<br>

или более сложных конструкций вёрстки. Обычные переносы строк в тексте по Enter при этом не учитываются.

Если html содержит картинку, то текст вываливается в одну строчку, а если html нет картинок, то текст прописывается как надо. Подскажите, пжста, есть ли решение, как уйти от этой проблемы? Заранее спасибо

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

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

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

Подскажите пожалуйста, как можно реализовать передачу PDF документа в "файлы и примечания" раздела по протоколу OData с использованием Http-запросов?

Нравится

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

Добрый день.

Для хранения файлов и ссылок по каждому разделу есть отдельная таблица. Например, для раздела [Обращения] - это CaseFile.
Для загрузки файлов используется сервис FileApiService (метод Upload).
Пример вызова сервиса можно посмотреть на примере детали "Файлы и ссылки" (FileDetailV2).

Добрый день, спасибо за быстрый отклик.
Но как я понимаю FileApiService можно использовать для обработки события upload в самой crm. А задача состояла в обратном: на сайте генерируется pdf файл и необходимо его передать в карточку договора в файлы и примечания.
Разобралась как это сделать с помощью OData. Необходимо сначала создать файл, к примеру в ContractFileCollection, с помощью POST с привязкой к Id договора и с необходимым типом, а потом уже в созданный Id документа в /Data записывать необходимый файл с помощью запроса PUT с Content-Type: application/octet-stream.

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

Добрый день!

А можно ли узнать, кто выдал права доступа на запись - пользователь вручную, создана по умолчанию или добавлена в бизнес-процессе?

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

Нравится

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

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

Права доступа на записи хранятся в таблице Sys[Имя_объекта]Right. Для каждой записи о правах есть колонки создал(CreatedbyID) и Изменил(ModifiedbyID).

"Павел Баштовой" написал:Для каждой записи о правах есть колонки создал(CreatedbyID) и Изменил(ModifiedbyID).

И как из них узнать, что поменялось автоматически по предыдущему БП, а что вручную?

"Владимир Соколов" написал:
Павел Баштовой пишет:

Для каждой записи о правах есть колонки создал(CreatedbyID) и Изменил(ModifiedbyID).

И как из них узнать, что поменялось автоматически по предыдущему БП, а что вручную?

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

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

Пишу PHP модуль для связи сайта с BPM. Есть какой-нибудь Wysywig редактор для построения SQL запросов? Писать такие запросы вручную это просто утомительно. К тому же не ясно, как проконтролировать скомпилированный запрос и обработанный DataService

{

            "QueryType": 0,
            "Columns": {
                "Items": {
                    "Name": {
                        "OrderDirection": 0,
                        "OrderPosition": 0,
                        "Caption": null,
                        "Expression": {
                            "ExpressionType": 0,
                            "ColumnPath": "Name"
                        }
                    },
                    "OwnerLogin": {
                        "OrderDirection": 0,
                        "OrderPosition": 0,
                        "Caption": null,
                        "Expression": {
                            "ExpressionType": 0,
                            "ColumnPath": "[WSysAccount:Contact:Owner].Login"
                        }
                    }
                }
            },
            "AllColumns": false,
            "IsDistinct": false,
            "RowCount": 1,
            "Filters": {
                "FilterType": 6,
                "ComparisonType": 0,
                "LogicalOperation": 0,
                "IsNull": true,
                "IsEnabled": true,
                "IsNot": false,
                "Items": {
                    "FilterByPhone": {
                        "FilterType": 1,
                        "ComparisonType": 9,
                        "LogicalOperation": 0,
                        "IsNull": true,
                        "IsEnabled": true,
                        "IsNot": false,
                        "LeftExpression": {
                            "ExpressionType": 0,
                            "ColumnPath": "[ContactCommunication:Contact].SearchNumber"
                        },
                        "RightExpression": {
                            "ExpressionType": 2,
                            "ColumnPath": null,
                            "Parameter": {
                                "DataValueType": 1,
                                "Value": "54326672198"
                            }
                        }
                    }
                }
            },
            "RootSchemaName": "Contact",
            "OperationType": 0
}';

Нравится

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

Андрей, здравствуйте!

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

Пусть так, а как проконтролировать какой SQL запрос получится из этого запроса? На примитивном запросе с одним условием еще более менее понятно, а вот делаю объединение запроса и привет. Например, хочу эмулировать запрос
SearchNumber in ("54326672198", "54326672197") /* пользователи и через 8ку заносят номера и через +7*/
ну или так SearchNumber="54326672198" or SearchNumber="54326672197"
и всё, не отрабатывает, пробовал и через RightExpressions[] и задавал два Items. В первом случае возвращается всегда error, а во втором случае если искать в первом item "54326672197" находит. если номер во втором item, то соответствий нет.

а уж такие запросы типа select * from dbo where id in (select id from dbo1 where x=y) я понимаю вообще не сделать

Добрый день, Андрей.
Мне кажется, что в Вашем случае значительно лучше подойдут sql view нежели сложные odata запросы. Просто создайте view в базе данных, которая будет Вам возвращать нужную выборку по простому запросу и обращайтесь к ней (view должна быть связана с объектом в конфигурации).
В описанном Вами случае, вьюха будет представлять union таблицы контактов с необходимыми полями и всеми вариантами написания номера. Запрашиваете у вьюхи номер в любом формате - она возвращает нужные данные контакта.
Соответственно, отдельная вьюха под каждую задачу.

Также, ознакомьтесь со статьями
https://academy.terrasoft.ru/documents/technic-sdk/7-9/rabota-s-obektam…
и
https://academy.terrasoft.ru/documents/technic-sdk/7-9/primery-zaprosov…
Чуть более сложные запросы в комбинации со вьюхой позволят построить выборку практически любой сложности.
Опять же, на вьюху можно навесить тригер в БД. Тогда можно вообще кастомные запросы обрабатывать.

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

Во время выполнения запроса:

var select = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "DimensionCustom"
});
select.addColumn("EntitySchemaUId", "EntitySchemaUId");
var levelColumn = select.addColumn("[ForecastDimensionCustom:DimensionCustom:Id].Level");
levelColumn.orderPosition = 1;
levelColumn.orderDirection = this.Terrasoft.OrderDirection.ASC;
select.addColumn("[ForecastDimensionCustom:DimensionCustom:Id].Id", "ForecastDimensionId");
select.filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL, "[ForecastDimensionCustom:DimensionCustom:Id].ForecastCustom", forecastId));
select.rowCount = 1;
select.getEntityCollection(function(response) {
        if (response.success) {
                var collection = response.collection;
                if (collection && collection.getCount() > 0) {
                        var item = collection.getItems()[0];
                        if (item) {
                                this.set("EntitySchemaUId", item.get("EntitySchemaUId"));
                                this.set("ForecastDimensionId", item.get("ForecastDimensionId"));
                        }
                        if (callback) {
                                callback.call(this);
                        }
                }
        }
}, this);

Получаю Ошибки при исполнении запроса:

Недопустимое имя столбца "DimensionCustomId".
↵Недопустимое имя столбца "ForecastCustomId

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

PS: Объекты ForecastDimensionCustom и DimensionCustom являются копиями базовых объектов из CoreForecast, см.прикрепленные файлы.

Нравится

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

Здравствуйте, Илья.

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

Для отладки ошибки будет полезным посмотреть какой запрос отправляется в базу данных при помощи Sql server managment studio или же утилиты fiddler2.

А как можно посмотреть запрос через Sql server managment studio ?

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

А как можно посмотреть запрос через Sql server managment studio ?


В смысле профайлером :)

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