Добрый день!

Необходимо реализовать в разделе Лиды в карточке Лида разделение поля "ФИО контакта" на 3 отдельных поля "Фамилия", "Имя" и "Отчество".

В мастере разделов я добавил 3 новых поля и хочу сделать стандартное поле "ФИО контакта" скрытым, но чтоб не переделывать логику работы карточек, думаю при сохранении Лида записывать значения полей фамиля+имя+отчество в поле "ФИО контакта"

Подскажите, пожалуйста, нормальное будет такое решение? И как можно реализовать автоматическое сохранение?

Я пока только разбираюсь в системе и её документации, нужной информации пока не нашел.

Нравится

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

Сделать поле ФИО контакта вычисляемым полем. статья https://academy.terrasoft.ru/documents/technic-sdk/7-15/dobavlenie-vychislyaemyh-poley

по аналогии делал для поля Название в разделе конфигурации:

attributes: {
"Name": {
	dataValueType: Terrasoft.DataValueType.STRING,
	dependencies: [
		{
			columns: ["Type", "Model", "EPMManufacturer"],
			methodName: "generateNewName"
		}
	]
}
},
methods: {
onEntityInitialized: function() {
	this.callParent(arguments);
	this.generateNewName();
},
generateNewName: function() {
	var sType = Ext.isEmpty(this.get("Type")) 
				? ""
				: this.get("Type").displayValue ;
	var sModel = Ext.isEmpty(this.get("Model")) 
				? "" 
				: " " + this.get("Model").displayValue;
	var sEPMManufacturer = Ext.isEmpty(this.get("EPMManufacturer")) 
							? "" 
							: " " + this.get("EPMManufacturer").displayValue;
	var result = sType + sEPMManufacturer + sModel;
	this.set("Name", result);
}
}

 

Сделать поле ФИО контакта вычисляемым полем. статья https://academy.terrasoft.ru/documents/technic-sdk/7-15/dobavlenie-vychislyaemyh-poley

по аналогии делал для поля Название в разделе конфигурации:

attributes: {
"Name": {
	dataValueType: Terrasoft.DataValueType.STRING,
	dependencies: [
		{
			columns: ["Type", "Model", "EPMManufacturer"],
			methodName: "generateNewName"
		}
	]
}
},
methods: {
onEntityInitialized: function() {
	this.callParent(arguments);
	this.generateNewName();
},
generateNewName: function() {
	var sType = Ext.isEmpty(this.get("Type")) 
				? ""
				: this.get("Type").displayValue ;
	var sModel = Ext.isEmpty(this.get("Model")) 
				? "" 
				: " " + this.get("Model").displayValue;
	var sEPMManufacturer = Ext.isEmpty(this.get("EPMManufacturer")) 
							? "" 
							: " " + this.get("EPMManufacturer").displayValue;
	var result = sType + sEPMManufacturer + sModel;
	this.set("Name", result);
}
}

 

Алексей Следь,

 Спасибо большое!

В итоге получился вот такой код:

		attributes: {
            "Contact": {
                dataValueType: Terrasoft.DataValueType.TEXT,
                dependencies: [
                    {
                        columns: ["UsrLastName", "UsrFirstName", "UsrMiddleName"],
                        methodName: "calculateContact"
                    }
                ]
            }
		},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {
            onEntityInitialized: function() {
                this.callParent(arguments);
                this.calculateContact();
            },
            calculateContact: function() {
                var sLastname = Ext.isEmpty(this.get("UsrLastName")) 
				? ""
				: this.get("UsrLastName");
 
                var sFirstname = Ext.isEmpty(this.get("UsrFirstName")) 
				? ""
				: this.get("UsrFirstName");
 
				var sMiddlename = Ext.isEmpty(this.get("UsrMiddleName")) 
				? ""
				: this.get("UsrMiddleName");
 
                var result = sLastname + " " + sFirstname + " " + sMiddlename;
                this.set("Contact", result);
			}
		},

DisplayValue убрал, так как с ним подставлялось в строку "не найденное значение".

Теперь не понятно, что делать со старыми Лидами делать, где контакт забит одной строкой, а разделенные поля фамилия, имя, отчество не заполнены.. Я там понимаю, что нужно сделать дополнительную обработку существующих лидов и заполнить значения разделив поле Контакт.. Только как это сделать лучше и в какую сторону копать не знаю. Можете подсказать? Может через БП или напрямую через SQL?

Сергей Бер пишет:
Может через БП или напрямую через SQL?

Без разницы - оба варианта подойдут. Реализуйте тот способ, что для Вас проще.

Если на объекте лида есть какая-то логика во встроенном или отдельном БП, уже завязанная на изменение названия, то при изменении поля при помощи SQL-запроса привязанное событие не запустится, это на всякий случай нужно учитывать. 

Сергей Бер пишет:
DisplayValue убрал, так как с ним подставлялось в строку "не найденное значение".

да, забыл предупредить. У меня это поля справочники. Поэтому я использую displayValue. 

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

Добрый день!

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

Нравится

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

Владимир, добрый день.

Для примера рассмотрим реалзиацию для объекта Обращения.

Одним из возможных вариантов реализации будет следующий:
1.На странице [Обращения], открыть мастер раздела и во вкладке [Решение и закрытие], добавить новое текстовое поле типа "Строка"
Например с названием "Причина перехода на следующую стадию" http://prntscr.com/i97vb7
2.Перейдя в мастере раздела на [Бизнес правила], создадим новое БП  http://prntscr.com/i97viu
Это правило говорит, что при изменении состояния обращения с "Новое" на "В работе",
поле "Причина перехода на следующую стадию" является обязательным к заполнению.
Обращаем Ваше внимание, что при создании БП в графе [Какое поле делать обязательным] следует указать название требуемой к заполнению строки из БД http://prntscr.com/i97vvk
3.После выполнения этих операций, мы видим, что при попытке пользователя перевести обращение к следующему состоянию,
он будет получать уведомление о том, что не заполнено обязательное поле указания причины http://prntscr.com/i97w4x 

При переходе по actiondashboard'у выполняется сохранение записи и валидация заполненных полей.

Спасибо, Андрей!

При реализации возникла проблема в связи с различиями в поведении ActionsDashboard и lookup-поля:

Имеется справочник QualifyStatus, он выведен на страницу LeadPageV2 через ActionDashboard, в разделе attributes страницы указаны дополнительные колонки кроме id и value:

"QualifyStatus": {
    lookupListConfig: {
        columns: ["Name", "StageNumber", "UsrIsTaken", "UsrIsOpportunity", "UsrIsDisqualified"]
    }
}

Но они не доступны в коде страницы работы через this.get("QualifyStatus"). Если же добавить на страницу Lookup с QualifyStatus и работать со справочником через него то данные поля становятся доступны

Кроме того, при неудачной валидации статус на ActionsDashboard перескакивает обратно, что не совсем логично

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

Т.е. this.get("QualifyStatus") возвращает объект в котором нет указанных колонок?

Именно 

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

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

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

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

Нравится

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

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

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

Данная проблема и обходные пути решения обсуждались тут:
http://www.community.terrasoft.ru/forum/topic/25239

Показать все комментарии
Предлагать сохранить (или предупреждать) , если из созданной или редактируемой карточки происходит переход на другую страницу. Например, так, как это сделано в Facebook, когда что-то начал вводить в поле статуса.
3 комментария

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

Почти каждый клиент, пробуя bpm'online спрашивает про эту возможность

К юбилею идеи ее могут и принять :)

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

Здравствуйте!
Подскажите, пожалуйста, как можно реализовать следующий функционал. Хочу при сохранении записи делать проверку и при определенных условиях не давать сохранять запись и выводить сообщение. Так вот для этого я в событие "Перед сохранением" моего объекта написал скрипт с моей проверкой и возвращал в нем false если не хотел сохранять запись. Но запись все равно сохраняется. Подскажите, пожалуйста что можно сделать чтобы это заработало и как еще вывести в MessagePanel сообщение о причинах при которых эта запись не сохраняется(аналог указан на картинке). Спасибо!

Нравится

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

Может вру, но вот в тройке я возвращаю true, чтобы запись не сохранялась, может и в BPM 5.х также!?
А на счет MessagePanel почитайте тут

Здравствуйте, Павел!
Можно добавить проверки в обработчик нажатия кнопки "ОК" и устанавливать булевский параметр в false, если проверка не прошла. А после Вашего скрипта ставить условный поток, который будет идти дальше в зависимости от параметра.

Можно повесить проверку на нажатие кнопки ОК.
OKBtnClick

В нижнем блоке:

Page.BaseMessagePanel.AddMessage(Warning, MyTextOfMessage, MessageType.Warning);
return true;

Спасибо! Помогло)

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

Вопрос: как это реализовать через стандартную кнопку?

ScriptTask2:

var AccountAddressCLADR =  UserConnection.EntitySchemaManager.GetInstanceByName("AccountAddressCLADR");
var entity = AccountAddressCLADR.CreateEntity(UserConnection);
var contactId = Page.DataSource.ActiveRowPrimaryColumnValue;
if(contactId == Guid.Empty ){
	Page.ThrowEvent("SaveContactNeeded");
	return true;
}
IsCanDelete = true;
if (entity.FetchFromDB(contactId)) {
 IsCanDelete = !entity.GetTypedColumnValue<Boolean>("ByDefault");
}
return true;

ScriptTask1:

string warningMessageId = "SomeMessageId";
string errorMessage = "Нельзя удалить адрес с установленным признаком <По умолчанию>";
MessagePanel messagePanel = ControlUtilities.FindControl(
                Page.AspPage.Controls[0], "BaseMessagePanel", true) as MessagePanel;
if (messagePanel != null) {
                messagePanel.Remove(warningMessageId);
                messagePanel.AddMessage(warningMessageId, Warning, errorMessage, MessageType.Warning);
}
return true;

На стандартную кнопку навешивается js-обработчик, см. в функции ScriptRegisterClientScriptExecute, унаследованной из BaseGridPage.

	public virtual bool ScriptRegisterClientScriptExecute(ProcessExecutingContext context) {
			string formatString = "{0}.on('click', function(el) {{ {1} }}, this)";
string script = GetRegisterQuestionScript();
if (!string.IsNullOrEmpty(script)) {	
	Page.AddScript(string.Format(formatString, Page.DeleteButton.ClientID, script));
}
...

Чтобы его отключить, можно в функции GetRegisterQuestionScript в своей странице написать вначале

return string.Empty; 

вместо логики.

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

Уже не раз сталкиваюсь с тем, что содержимое вкладки Описание не сохраняется, даже после нажатия на кнопку Сохранить! Причем узнаешь это только когда данные пропали.

Не описать как это вымораживает, когда теряется и труд и время.

- как отловить этот глюк?
- как узнать текущую вверсию клиента ТС?

Нравится

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

Добрый день!

"Отловить" можно только выявив порядок действий, после которых не сохраняются данные.
Вариант решения - обновление до самой последней сборки в рамках Вашей версии, которая написана в коне запуска программы (например, 3.3.2.127).

Столкнулись с такой же проблемой в версии 3.3.0.83. Возникает только на детали [Описание] раздела [Проекты].

Добрый день!

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

Да, отловить такую последовательность будет тяжеловато. А вот если не нажимать кнопку Сохранить, то и в разделе Счета и в разделе Документы в детали Описание данные то сохраняются, то не сохраняются. С чем это связано? Как лечить - понятно - нажимать Сохранить, а вот почему такая нестабильность?

Скажу больше, иногда (но редко) инфа не сохраняется и после нажатия на кнопке Сохранить!

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

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

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

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

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

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

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

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

Какую версию Вы используете?
Дело в том, что при переходе в другой раздел или даже если закрыть приложение, текст на детали описание сохраняется - проверял на 3.4.0.121.

Как вариант: можно попробовать самостоятельно переопределить логику сохранения данных детали. Для этого вызывайте метод rdcDesciption.SaveToDataset();

Еще раз перепроверил - не сохраняется в моей версии: 3.3.2.266, БД Оракл, сервисы от 3.1.Х.Х

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

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

Проверил на 3.3.2 - Вы правы.
Для исправления этой проблемы Вам необходимо:

1. В Террасофт Администратор в скрипте scr_BaseWorkspace в функции wnd_BaseWorkspaceOnProfileSerialize(Window, Node) добавить вызов функции SaveDescription();

function wnd_BaseWorkspaceOnProfileSerialize(Window, Node) {
	Node.SetAttributeAsStr('SavedGroupID', dlGroups.Dataset('ID'), '');
	SaveDescription();
}

2. В этом же скрипте объявите эту функцию:

function SaveDescription() {
	var DescriptionDetail = Self.ComponentsByName('wndDescriptionDetail');
	if (DescriptionDetail) {
		var DataseLink = DescriptionDetail.Window.ComponentsByName('dlData');
		if (DataseLink.Dataset.IsActive) {
		        DataseLink.Dataset.Close();
		}
	}
}

Сохраните изменения и перезапустите клиентское приложение.

Дмитрий, спасибо большое. Ваш код действительно помог. Только у меня функции wnd_BaseWorkspaceOnProfileSerialize(Window, Node) вообще не было в данном скрипте, пришлось создать её и привязать на событие OnProfileSerialize окна wnd_BaseWorkspace.

Подскажите, пожалуйста, нужна ли мне строка кода Node.SetAttributeAsStr('SavedGroupID', dlGroups.Dataset('ID'), ''); если упоминания о SavedGroupID в коде нет и для чего она должна служить?

Судя по всему, она сохраняет позицию в дереве групп при закрытии раздела. А при открытии, соответственно, можно восстанавливать. Если такая логика нужна, можно перенести и её.

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

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

Всем спасибо, реализовал у себя подобную полезную функцию.

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

При сохранении карточки Контакта выдается ошибка
Ошибка сохранения записи. Оригинальное сообщение об ошибке: Недопустимое имя объекта "dbo.Communication1TypeName"
Карточка не сохраняется. В чем может быть ошибка?

Нравится

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

Система жалуется на сохранение первого средства связи.
Что Вы добавили в карточку контакта?
Сделайте скриншот заполненой карточки контакта перед сохранением.

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

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

Скорее всего, проблема в запросе. Судя по сообщению, обращение происходит не к таблице, а непонятно куда. Для корректной работы должно быть dbo.tbl_Account.Communication1TypeName

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

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

Столкнулся с интересной ситуацией при переводе проектного решения с версии 3.2 на версию 3.3. Карточка проекта не закрывалась при нажатии на кнопку OK. Запись в базе при этом сохранялась.

В результате отладки выяснил, что в 3.3 базовая карточка редактирования была доработана и теперь, если метод Post набора данных карточки возвращает 0, карточка не закрывается.

Метод Post набора данных возвращает количество строк, которые были затронуты при выполнении запроса. В моем случае, этот метод возвращал 0, несмотря на то, что запись сохранялась.

Более внимательный взгляд на таблицу проектов показал, что для нее есть несколько триггеров After Update, созданных в рамках проектного решения. Собственно, результат выполнения этих триггеров и возвращается методом Post в конечном итоге.

Чтобы все отрабатывало как нужно, и метод Post возвращал именно количество записей непосредственно затронутых запросом, в триггерах следует включать опцию NOCOUNT.

Для этого в каждом триггере первой строкой необходимо записать

SET NOCOUNT ON

Нравится

Поделиться

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