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

Нравится

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

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

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

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

Добрый день. При копировании продажи не копируются продукты в новую продажу. Как изменить логику копирования продажи?

Нравится

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

Добрый день, Александр!

Данная идея уже зарегистрирована у команды разработки для реализации в следующих версиях системы. Номер проблемы 3762
Если Вы хотите реализовать перенос своими силами, для решения данного вопроса Вы можете воспользоваться базовым функционалом системы в виде бизнес-процессов, создав свой процесс. В данном процессе необходимо первым элементом вычитать создаваемую продажу, вторым чтением данных ту, из которой создается, третьим элементом "чтение данных" вычитать деталь "продукт в продаже" и четвертым элементом "добавление данных" перенести все продукты. Перед построением своего процесса рекомендуем ознакомится с руководством пользователя по работе с бизнес-процессами: https://academy.terrasoft.ua/documents/technic-bpms/7-9/obzor-funkciona…

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

"Мария Ватулина" написал:

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

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

Решение с процессом корректно, однако реализация должна быть другой. Есть два варианта:
1) Требующий навыков программирования на JS (для создания действия, которое будет вызывать процесс из раздела)
2) Не требующий навыков программирования.

В первом варианте:

  • Создайте параметр с типом "Уникальный идентификатор". Назовем его RecordId
  • Общая структура процесса

  • Начальный элемент
  • Элемент добавить данные в режиме выборки. Добавляем данные в объект "Продажа". Выборка по объекту "Продажа". Фильтр выборки Id = [#RecordId#]
  • Элемент добавить данные в режиме выборки. Добавляем данные в объект "Продукт в продаже". Выборка по объекту "Продукт в продаже". Фильтр выборки Продажа = [#RecordId#]
  • Конец процесса

Также можно вначале процесса добавить проверку, что параметр RecordId != Guid.Empty (проверка, что процесс запущен по записи, а не вручную).

Дополнительно нужно создать действие в разделе, который вызовет указанный процесс по выделенной записи. Например, можно создать кнопку в разделе. Подробнее можно найти по ссылке:
http://www.community.terrasoft.ru/forum/topic/14042

В втором варианте:

    Общая структура процесса
  • Начальный элемент
  • Автогенерируемая страница с полем выбора из справочника "Продажа"
  • Элемент добавить данные в режиме выборки. Добавляем данные в объект "Продажа". Выборка по объекту "Продажа". Фильтр выборки Id = [#Автогенерируемая страница.Продажа#]
  • Элемент добавить данные в режиме выборки. Добавляем данные в объект "Продукт в продаже". Выборка по объекту "Продукт в продаже". Фильтр выборки Продажа = [#Автогенерируемая страница.Продажа#]
  • Конец процесса

Такая реализация требует дополнительного действия пользователя.

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

Есть код

getCurrencyRate: function(LogCurrencyRow) {
                                var LogCurrencyRate = 0;
                               
                                var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "CurrencyRate"});
                                esq.addColumn("Rate");
                                var _tomorrow = new Date();
                                _tomorrow.setDate(_tomorrow.getDate() + 1);
                                var _yesterday = new Date();
                                _yesterday.setDate(_yesterday.getDate() - 1);
                               
                                _tomorrow = Terrasoft.endOfDay(_tomorrow);
                                _yesterday = Terrasoft.startOfDay(_yesterday);
                               
                               
                                esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
                                                this.Terrasoft.ComparisonType.EQUAL, "Currency", LogCurrencyRow));
                                esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
                                                this.Terrasoft.ComparisonType.GREATER, "StartDate", _yesterday));
                                esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
                                                this.Terrasoft.ComparisonType.LESS, "StartDate", _tomorrow));

                                esq.getEntityCollection(function(response) {
                                        if (response && response.success) {
                                                if (response.collection.getCount() > 0) {
                                                        var result = response.collection.getItems()[0];
                                                        LogCurrencyRate = result.get("Rate");
                                                } else {
                                                        LogCurrencyRate = 0;
                                                }
                                               
                                        }
                                        else {
                                                LogCurrencyRate = 0;
                                        }
                                }, this);
                                return LogCurrencyRate;
                        },

result.get("Rate"); есть значение. Но оно не возвращается функцией.

Не могу понять специфики, подскажите.

Нравится

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

Интересно, вот так сработает?

var result = response.collection.collection.getItems()[0];
LogCurrencyRate = result.get("Rate");

Не могу понять почему
esq1.getEntityCollection(function(response)
в if (response && response.success) { не попадает
и дальше проходит по коду.
Что не так?

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

Может как то связано что в одной функции я использую 2 function(response)

1. esq.getEntityCollection(function(response)
2. esq1.getEntityCollection(function(response)

1 -й работает
2 й нет

"Юсупов Марат" написал:Что не так?

function(response) {...}

Это коллбек от функции esq1.getEntityCollection.
Всё-таки попробуйте

var result = response.collection.collection.getItems()[0];

Данила он туда даже не попадает. Проскакивает.

"Юсупов Марат" написал:Проскакивает

Секунду. Он и должен проскочить. Потом пройдет немного времени, придёт ответ от бд, начнёт отрабатывать

function(response) {...}

У вас так происходит, или вообще ничего не работает(даже спустя некоторое время)?

Спустя некоторое происходит но уже значений нет.

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

Вы написали не синхронный код и ожидаете от него синхронного поведения. Функция, передаваемая в метод getEntityCollection вызывается асинхронно после ответа от базы данных. Она будет вызвана в другом контексте и уже после того как метод getCurrencyRate отработает.

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

Илья, спасибо. помогло.

Terrasoft.chain(
									function(next) {
										//запрос
										var selectRate = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "CurrencyRate"});
										selectRate.addColumn("Rate");
										var _tomorrow = new Date();
										_tomorrow.setDate(_tomorrow.getDate() + 1);
										var _yesterday = new Date();
										_yesterday.setDate(_yesterday.getDate() - 1);
 
										_tomorrow = Terrasoft.endOfDay(_tomorrow);
										_yesterday = Terrasoft.startOfDay(_yesterday);
 
										// если у нас рубль то берем курс валюты сверху
										if (LogCurrencyRow.value === LogConstants.Currency.rub) {
											selectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
													this.Terrasoft.ComparisonType.EQUAL, "Currency", LogCurrencySCC.value));
										} else {
											selectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
													this.Terrasoft.ComparisonType.EQUAL, "Currency", LogCurrencyRow.value));
										}
										selectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
												this.Terrasoft.ComparisonType.GREATER, "StartDate", _yesterday));
										selectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
												this.Terrasoft.ComparisonType.LESS, "StartDate", _tomorrow));
										selectRate.getEntityCollection(function(response) {
											if (response && response.success) {
												if (response.collection.getCount() > 0) {
													var result = response.collection.getItems()[0];
													this.set("LogCurRate2SCC", result.get("Rate"));
													this.save({isSilent: true});
													next();
												}
											}
										}, this);
									},
									function(next) {
										//обработка данных запросов
										if (this.get("LogCurrencyRow").value === 0 || this.get("LogCurrencyRow").value === "") {
											var currencyIN = null;
											switch (LogCurrencyRow.value) {
												//доллар
												case (LogConstants.Currency.usd) :
													currencyIN = "usd";
													break;
												//евро
												case (LogConstants.Currency.eur) :
													currencyIN = "eur";
													break;
											}
											var serviceData = {
												param: currencyIN
											};
											ServiceHelper.callService("LogGetCurrencyCBRF", "getCurrencyFromCBRF",
												function(response) {
													if (response.getCurrencyFromCBRFResult >= 0) {
														this.set("LogCurRate2SCC", response.getCurrencyFromCBRFResult);
													} else {
														this.showInformationDialog(response.getCurrencyFromCBRFResult);
													}
												},
												serviceData, this);
											this.save({isSilent: true});
											next();
										}
										else {
											next();
										}
									},
									function(next) {
										//вычисляем итоговую стоимость в валюте РСП
										this.calculateCostCur(LogCurrencySCC, LogCurrencyRow, this.get("LogCurRate2SCC"));
										next();
									},
								this);

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

К примеру есть внешний вызов

debugger;
LogCurrencyRate2 = this.getCurrencyRate(LogCurrencyRow.value);
									if (LogCurrencyRate2 > 0) {
										LogTotalCostRowCur = (this.get("LogTotalCostRow") * LogCurrencyRate) / LogCurrencyRate2;
									}

а в this.getCurrencyRate(LogCurrencyRow.value);

getCurrencyRate: function(LogCurrencyRow) {
				debugger;
				var LogCurrencyRate = 0;
				var _tomorrow = new Date();
 
				_tomorrow.setDate(_tomorrow.getDate() + 1);
				var _yesterday = new Date();
				_yesterday.setDate(_yesterday.getDate() - 1);
 
				_tomorrow = Terrasoft.endOfDay(_tomorrow);
				_yesterday = Terrasoft.startOfDay(_yesterday);
 
				Terrasoft.chain(
					function(next) {
						//запрос
						var SelectRate = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "CurrencyRate"});
						SelectRate.addColumn("Rate");
 
						SelectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
								this.Terrasoft.ComparisonType.EQUAL, "Currency", LogCurrencyRow));
						SelectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
								this.Terrasoft.ComparisonType.GREATER, "StartDate", _yesterday));
						SelectRate.filters.addItem(Terrasoft.createColumnFilterWithParameter(
								this.Terrasoft.ComparisonType.LESS, "StartDate", _tomorrow));
 
						SelectRate.getEntityCollection(function(response) {
							if (response && response.success) {
								if (response.collection.getCount() > 0) {
									var result = response.collection.getItems()[0];
									LogCurrencyRate = result.get("Rate");
									next();
								}
							}
						}, this);
 
					},
					function(next) {
						return LogCurrencyRate;
					},
				this);
			},

И почему то программа по нему 2 раза проходит...первый раз ок..значения есть...а вторая непонятная проходка уже нет значение.

Документацию о методах chain и next, Вы можете почитать на SDK https://academy.terrasoft.ru/jscoresdk/

Также, судя по предоставленному коду, Вам достаточно вы функции обратного вызова вызывать следующий метод в правильном контексте. Контекст можно задать функцией bind. Упрощенный пример:

test: function() {
	var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
		rootSchemaName: "Lead"
	});
	esq.addColumn("CreatedOn");
	esq.execute(function(response){
		if(response.success){
			this.save({isSilent: true});
			this.other();
		}
	}.bind(this));
},
other: function() {
	alert("!");
}
Показать все комментарии

Коллеги, добрый вечер!

Мы реализовали действие в разделе Юр. лиц, которое инициирует загрузку данных из сервиса СПАРК и записывает их в базу с помощью хранимой процедуры. Возникла проблема, связанная с тем, что по загруженным Юр. лицам не запускаются процессы (стартовые события процессов - сигнал добавление/изменение).

Кто-нибудь с таким сталкивался?

Нравится

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

Небольшое дополнение - в действии используется метод showBodyMask (this.showBodyMask();) для отображения анимации загрузки. Если это важно.

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

Стартовые сигналы не реагируют на прямые запросы к БД (добавление/изменение/удаление записей).
Сигналы срабатывают если запрос выполняется через EntitySchemaQuery - https://academy.terrasoft.ua/documents/technic-sdk/7-9/rabota-s-dannymi
Вы можете решить вашу задачи с помощью триггеров в БД или создать процесс, который будет периодически запускаться с помощью планировщика и обрабатывать интересующие записи.

Поясните, пожалуйста, ваш ответ. EntitySchemaQuery используется для чтения данных.

У нас также реализована загрузка данных через конфигурационный сервис с помощью механизма - https://academy.terrasoft.ua/documents/technic-sdk/7-9/postroenie-zapro….

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

В конфигурационном сервисе тоже нужна дополнительная логика?

Сергей, здравствуйте!

Классы Insert, Update, Delete не вызывают срабатывания сигналов, поскольку запись не ведется на уровне ESQ.

Таким образом процессы запущены не будут.

Пример работы с ESQ можно найти в схеме ImapClient метод SaveActivityParticipants. При таком создании записей процессы будут запущены.

Коллеги, а триггеры в БД имеется в виду на добавление/изменение?

Если у нас будет обновление поля через ESQ и одновременно будет создан триггер на изменение этого поля в БД, не будет ли двойного срабатывания стартового события одного и того же процесса?

И какая логика должна выполняться после срабатывания триггера в БД?

Сергей, здравствуйте!

"Сергей Фролов КРОК" написал:

Коллеги, а триггеры в БД имеется в виду на добавление/изменение?

Если у нас будет обновление поля через ESQ и одновременно будет создан триггер на изменение этого поля в БД, не будет ли двойного срабатывания стартового события одного и того же процесса?

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

Спасибо за информацию!

Подскажите, а как должен выглядеть триггер в БД, инициирующий запуск процессов?

"Сергей Фролов КРОК" написал:Подскажите, а как должен выглядеть триггер в БД, инициирующий запуск процессов?

Я надеюсь вопрос не про кварц тригеры? Механизм который позволяет запускать процессы по расписанию.
https://academy.terrasoft.ru/documents/technic-sdk/7-4-0/zapusk-process…

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

var entitySchemaManager = _userConnection.GetSchemaManager("EntitySchemaManager") as EntitySchemaManager;
var activityParticipantSchema = entitySchemaManager.GetInstanceByName("ActivityParticipant");
var activityParticipant = activityParticipantSchema.CreateEntity(_userConnection) as ActivityParticipant;
activityParticipant.SetDefColumnValues();
activityParticipant.ActivityId = _currentEmailActivityId;
activityParticipant.ParticipantId = contactId;
activityParticipant.RoleId = roleId;
activityParticipant.Save();

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

Коллеги, добрый день.

Подскажите пожалуйста, можно ли в bpm настроить интервал синхронизации с почтой? Например, подключено несколько почтовых ящиков (ящик1@mail.ru, ящик2@mail.ru). Мне нужно, чтобы письма с ящика ящик1@mail.ru синхронизировались в течении 1 минуты, а ящик2@mail.ru - 60 минут.
Присутствует системная настройка "Интервал синхронизации с почтовым ящиком", но эта настройка применяется, как я понимаю, для всех ящиков.

Нравится

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

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

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

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

Существует ли возможность инициировать проверку всех установленных пакетов на предмет наличия обновлений и установку оных в случае обнаружения ?

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

Нравится

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

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

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

Более подробно с процессом обновления пакета из SVN выможете ознакомиться по ссылке: https://academy.terrasoft.ru/documents/technic-sdk/7-9/obnovlenie-paket….

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

В типовом окне выбора как и положено у модальных окон - присутствует элемент управления модальным окном "закрыть".
:smile: в простонародии: "крестик"

Вопрос: Существует ли какая либо конфигурационная настройка на этот счет для вызова окна через openLookup(config)
Т.к. в нашем случае бизнес-логика в идеале предусматривает безусловную реакцию пользователя на предложенный выбор, хотелось бы вместо обработки результатов, просто исключить у пользователя "далее-далее-крестик-крестик-готовщика" возможность закрыть это окно.

PS: Отключение кнопки закрытия окна, тоже не silver bullet т.к. пользователь просто может нажать "выбрать" - ничего на самом деле не выделив. И как сопутствующий вопрос - можно ли регулировать это поведение в типовом окне выбора, таким образом чтобы кнопка "Выбрать" например была не активной пока пользователь не произведет выбор, или например генерировала уведомление об обязательности выбора значения ?

Нравится

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

Здравствуйте,
Вы конечно можете написать глобальный css стиль который скроет крестик, или переписать LookupPageViewGenerator для блокировки кнопки выбор. Но логичнее наверно прописать обязательность заполнения лукапного поля, на странице, на которой данный лукап и выбирается. Безусловно или по условию: https://academy.terrasoft.ru/documents/technic-sdk/7-8/pravilo-bindpara…

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

В типовом окне выбора как и положено у модальных окон - присутствует элемент управления модальным окном "закрыть".
:smile: в простонародии: "крестик"

Вопрос: Существует ли какая либо конфигурационная настройка на этот счет для вызова окна через openLookup(config)
Т.к. в нашем случае бизнес-логика в идеале предусматривает безусловную реакцию пользователя на предложенный выбор, хотелось бы вместо обработки результатов, просто исключить у пользователя "далее-далее-крестик-крестик-готовщика" возможность закрыть это окно.

PS: Отключение кнопки закрытия окна, тоже не silver bullet т.к. пользователь просто может нажать "выбрать" - ничего на самом деле не выделив. И как сопутствующий вопрос - можно ли регулировать это поведение в типовом окне выбора, таким образом чтобы кнопка "Выбрать" например была не активной пока пользователь не произведет выбор, или например генерировала уведомление об обязательности выбора значения ?

Нравится

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

Здравствуйте,
Вы конечно можете написать глобальный css стиль который скроет крестик, или переписать LookupPageViewGenerator для блокировки кнопки выбор. Но логичнее наверно прописать обязательность заполнения лукапного поля, на странице, на которой данный лукап и выбирается. Безусловно или по условию: https://academy.terrasoft.ru/documents/technic-sdk/7-8/pravilo-bindpara…

Обязательность поля для заполнения в данном случае не очень подходит, вернее базовая логика обработки "не заполненности" обязательных полей- т.к. в случае обязательности поля - пользователю выводится сообщение о том, что не заполнено одно или несколько обязательных полей, перечисляются их наименования, и сохранение карточки прерывается, после чего карточка остается в режиме ввода данных т.е. подразумевается что пользователь найдет указанные в сообщении поля, заполнит их и нажмет "Сохранить".
Во-первых работать с карточкой невозможно пока не закроешь оповещение в котором указаны поля для заполнения. (А стало быть пользователю надо их запомнить или записать :cry: в идеале такие уведомления надо делать интегрированными в UI а не модальной нотификацией, так как сделаны предупреждения и ошибки в конфигураторе например, текст которых остается видимым и с интерфейсом можно продолжить работу)
Во-вторых в некоторых карточках очень перегруженный интерфейс и поиск самого поля которое необходимо заполнить во множестве вкладок и т.д. - отнимает время у сотрудника (если это горячая линия, то эти 10-20 секунд в конечном итоге превращаются в минуты которые никому из клиентов ждать не хочется)
В третьих, если у Вас бизнес-логика подразумевает фиксацию совершения какого либо действия во времени, то в данном случае Вам потребуется вводить дополнительную проверку в логику сохранения карточки (т.к. фактически заполнение произойдет когда-то потом а не по нажаию кнопки) а не совершения какого либо действия чтобы отметить время совершения.
Ну и в конце концов - это просто удобно для пользователя, чтобы система предлагала ему выбор автоматически, если он что-то забыл.

Добрый день.

Магической системной настройки, убирающей отображение кнопки "закрыть" нету, необходимо переписывать логику самого модального окна. Вам стоит обратить внимание на 3 схемы: LookupPage, LookupPageViewGenerator и LookupPageViewModelGenerator. Для удаления кнопки закрыть - Вам стоит смотреть в сторону удаления кода генерации closeIconContainer в LookupPageViewGenerator. Для изменения логики кнопки "Выбрать" - переопределить конфиг для SelectButton в LookupPageViewGenerator, а также добавить логику в LookupPageViewModelGenerator.

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

Добрый день!

Доводилось ли кому реализовывать функционал для сложных взаимосвязей в холдинге?

Конкретно, несколько задач:
1) У одной компании может быть несколько "материнских компаний" - акционеров.
2) Между компаниями могут быть дополнительные взаимосвязи
3) В итоге на связях должны и присутствовать контакты - бенефициары
4) На схеме необходимо отображать и другие типы связей, а не только "holding - affiliate)

Думаю, что для банков такое должны были делать.

connected to

Нравится

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

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

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

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

Доброго времени суток!
Требует помощь с пониманием как работает TimezoneContainer у контакта, для того чтобы по аналогии сделать её для контрагента. Кто с таким сталкивался, прошу помощи.

Нравится

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

уууух. пришло время костылей

define("AccountPageV2", ["TimezoneGenerator", "TimezoneMixin"], function() {
	return {
	entitySchemaName: "Account",
	mixins: {
		TimezoneMixin: "Terrasoft.TimezoneMixin"
	},
	methods: {
		onEntityInitialized: function() {
			this.callParent(arguments);
			this.mixins.TimezoneMixin.init.call(this);
		},
		onDetailChanged: function(detail) {
			this.callParent(arguments);
			if (detail.schemaName === "AccountAddressDetailV2") {
				this.updateTimezone();
			}
		},
		updateTimezone: function() {
			this.mixins.TimezoneMixin.init.call(this);
		},
		setContactTimeConfig: function(accId, callback, scope) { //метод из TimeZoneMixin, его надо расковырять
			var func = function(contactTimeConfig) {
				var isValid = this.isConfigValid(contactTimeConfig);
				if (isValid) {
					this.set("ContactTimeConfig", contactTimeConfig);
					if (callback && this.Ext.isFunction(callback)) {
						callback.call(scope);
					}
				} else {
					this.log(Resources.localizableStrings.ContactTimeConfigInvalidFormatException,
							Terrasoft.LogMessageType.WARNING);
				}
			};
			this.getAccountTimeZone(func, accId);
		},
		getAccountTimeZone: function(callback, accId) {
			var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "AccountAddress"});
			esq.addColumn("City.TimeZone.Name", "TZName");
			esq.addColumn("City.TimeZone.Offset", "Offset");
			esq.addColumn("City.Name", "CityName");
			esq.filters.addItem(esq.createColumnFilterWithParameter(3, "Account", accId));
			esq.getEntityCollection(function (result) {
				var info = result.collection.collection.items[0].values; //По-идее нужно лезть в кучу миксинов/утилит/хелперов с сервисами, но можно и так вытащить инфу по городу. Тут я беру 1 попавшийся из AccountAddress. Можно дополнить фильтрами
				var offset = info.Offset === "GMT" ? 0 : parseInt(info.Offset.split("GMT")[1].split(":")[0]);
				var time = new Date(new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate(), new Date().getUTCHours(), new Date().getUTCMinutes(), new Date().getUTCSeconds());
				time.setUTCHours(time.getUTCHours() + offset);
				var contactTimeConfig = {
					equals: true,
					location: info.CityName,
					minutesOffset: offset*60,
					time: time,
					timeZone: info.TZName
				};
				this.callback.call(this.scope, contactTimeConfig);
			}.bind({callback: callback, scope: this}));
		}
	},
	diff: [
		{
			"operation": "insert",
			"name": "TimeZoneContainer",
			"parentName": "AccountPhotoContainer",
			"propertyName": "items",
			"values": {
				"itemType": Terrasoft.ViewItemType.CONTAINER,
				"generator": "TimezoneGenerator.generateTimeZone",
				"wrapClass": ["timezone-container"],
				"visible": true,
				"timeZoneCaption": {"bindTo": "TimeZoneCaption"},
				"timeZoneCity": {"bindTo": "TimeZoneCity"},
				"tips": []
			}
		}
	]};
});

Ну и ещё надо навесить немного стилей (пр. убрать часы под контейнер с обогащение данных). Но мне лень)

Варфоломеев Данила, благодарю)
Дальше разберусь что да как.

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