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

Пример ситуации:

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

Ну или как часто бывает у меня - Создается продажа из карточки, процесс начался, и база очень долго создает активность (да, на это бывает уходит минуты две, но это уже вопрос по работе с СУБД Oracle), но пользователь уже зашел в карточку, и когда активность все же создалась то на панели действий ее нет так как она создалась когда у кейса выбрана стадия и панель действий загрузилась уже

Нравится

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

Пример ситуации:

Менеджер сидит и на втором мониторе смотрит фильм, 

Отличное начало.laugh

 

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

 

Конкретно с панелью действий работают сообщения ReloadDashboardItems (отправляется из BaseMiniPage) и ChangeDashboardTab (из ActivityMiniPage):

/**
 * Publishes events after entity save.
 * @protected
 * @param {Function} [callback] Callback-function.
 * @param {Object} [scope] Callback execution context.
 */
publishOnSaveEvents: function(callback, scope) {
	this.sandbox.publish("ReloadDashboardItems", {
		id: this.get("Id")
	});
	this.Ext.callback(callback, scope || this);
},
/**
 * @inheritdoc BaseMiniPage#close
 * @override
 */
close: function() {
	if (this.destroyed) {
		return;
	}
	this.sandbox.publish("ChangeDashboardTab", null);
	this.callParent(arguments);
},

 

Они принимаются в BaseActionsDashboard:

/**
 * Subscribe on events of sandbox.
 * @protected
 */
subscribeSandboxEvents: function() {
	var sandbox = this.sandbox;
	sandbox.subscribe("ReloadDashboardItems", function() {
		this.onReloadDashboardItems();
	}, this);
	sandbox.subscribe("ChangeDashboardTab", function(tabName) {
		this.setActiveTab(tabName);
	}, this);
},

Далее срабатывают обработчики в этой же или дочерних схемах.

 

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

 

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

Но как это сделать из бизнес процесса?

Я создал замещение объекта "Активность", в нем добавил сообщение после создания записи. Создал событийный процесс что реагирует на это сообщение, в нем создал класс с колонкой Id (так как в подпищике смотрю эту колонку ждет)

	public class idNumberOpportunity
    {
		public Guid Id { get; set; }
    }

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

Entity.GetTypedColumnValue<Guid>("OpportunityId") != Guid.Empty

и в сценарии запустил код преобразовав сообщение в нужный вид преобразовав в Json формат (на выходе в js вышло так { "Id": "22345200-abe8-4f60-90c8-0d43c5f6c0f6"})

var userConnection = Entity.UserConnection;
var KtIdOpportunuty = new idNumberOpportunity();
KtIdOpportunuty.Id = Entity.GetTypedColumnValue<Guid>("OpportunityId");
MsgChannelUtilities.PostMessage(userConnection, "ReloadDashboardItems", JsonConvert.SerializeObject(KtIdOpportunuty));
return true;

Но видимо подписка так не срабатывает.

Что я не так делаю, подскажите?

Попробуйте поставить отладчик в onReloadDashboardItems, так будет видно, доходит ли Ваше сообщение и чем отличается от настоящего.

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

Может кто сталкивался с таким.

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

Можно зафильтровать добавив в замещаемом модуле код для атрибута

"Owner": {
	"dataValueType": Terrasoft.DataValueType.LOOKUP,
	"lookupListConfig": {
		filter: function() {
			var filterGroup = Ext.create("Terrasoft.FilterGroup");
			filterGroup.add("IsUser",
				Terrasoft.createColumnIsNotNullFilter("[SysAdminUnit:Contact].Id"));
			filterGroup.add("IsActive",
				Terrasoft.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL,
					"[SysAdminUnit:Contact].Active",
					true));
			return filterGroup;
		}
}

В продаже это нормально сработало, но в активностях не как не хочет работать фильтр.

Может кто в курсе почему?

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

Нравится

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

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

Попробуйте посмотреть, какой запрос идёт в одном и другом случае. Сначала — запрос от браузера к веб-сервису, его можно увидеть в «Инструментах разработчика». Если не поможет понять и сайт развёрнут локально, можно запустить SQL-профайлер и посмотреть запросы уже на уровне базы.

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

Проверил все наследования - только в ActivityPageV2 в NUI rfgtnt есть логика через атрибут

"Owner": {
	dataValueType: Terrasoft.DataValueType.LOOKUP,
	lookupListConfig: {filter: BaseFiltersGenerateModule.OwnerFilter}
}

и наследование идет от модуля что наследовался от выше указанного в NUI пакете. У себя в замещенном модуле его и заместил

Теперь попробуйте посмотреть запрос. Если Ваш фильтр идёт одновременно с этим и их условия мешают, это должно быть видно.

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

Добрый день,

 

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

 

Имеется "Автогенерируемая страница", в которой 4 поля (Отправитель, Получатель, Дата начала, Дата завершения). 

  1. Отправитель - сотрудник, уходящий в отпуск
  2. Получатель - заместитель
  3. Дата начала - с какого дня начинают передачу активностей на заместителя
  4. Дата завершения - когда закончить передачу и завершить бизнес-процесс.

 

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

Нравится

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

_KSL_,

 

В таком случае Вам нужно следующее.

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

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

Может быть проще использовать уже готовый бизнес-процесс по делегированию прав или модифицировать его? https://marketplace.terrasoft.ru/template/delegirovanie-prav-dostupa-na…

Сигнал не нужен, ведь данный БП запускается вручную.

После автогенерируемой страницы читаем первую запись Activity с нужными параметрами (от-до, где Ответственный = Сотрудник, ну и задача еще не завершена).

Если такая запись найдена (Id!=Guid.Empty), то модифицируем Activity, устанавливая Ответственный = Заместитель.

И снова возвращаемся к чтению записи Activity.



Конечно, нужно спрогнозировать ориентировочное количество возможных задач.



И, возможно, подумать, а как возвращать ещё не выполненные задачи после отпуска

Владимир Соколов,

 

Спасибо за ваши ответы.

 

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

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

_KSL_,

 

В таком случае Вам нужно следующее.

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

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

Алла Савельева,

Спасибо за ответ 

 

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

_KSL_,

А что мешает в том случае, если даты отпуска изменятся, откорректировать их в срм?

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

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

Алла Савельева,

 

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

 

Сотрудник, который уходит в отпуск, должен запустить данный процесс. При запуске открывается "Автогенерируемая страница", в который имеется 4 поля (Отправитель - сотрудник, уходящий в отпуск, Получатель - кому будем переназначать активность, Дата начала и Дата завершения - с какого и до какого чисел будем переназначать).

 

Далее происходит чтение данных с объекта "Активность" и изменение данных "Активность" на основании условий, т.е. Ответственный = Отправитель, Дата завершения>Дата создания >= Дата начала. 

 

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

 

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

 

Через делегирование прав не могу реализовать, т.к. Ответственный не меняется. А получателю придется самому искать задачи.

 

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

 

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

 

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

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

 

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

 

Правильно ли я понял, что я должен хранить к примеру в справочнике данные по отпускам(Сотрудник, Заместитель, Дата начала отпуска, Дата завершения).

И затем запускать процесс, который будет в определенное время менять Ответственного.

 

Но тогда не совсем понимаю как нужно будет организовать процесс.

Как Вы можете переназначит новые, их же ещё нет?

Если делаете логику на моменте создания или регулярно по планировщику, то нужно где-то брать информацию, у кого, на кого и с какого по какое отпуск.

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

 

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

 

Из полей Автогенерируемой страницу данные переходили в чтение данных, как условия (Ответственный=у кого, Завершения>Дата создания>=Начало). Далее шло изменение данных с такими же условиями, но меняли Ответственный=кому. Далее шел условный поток, в  котором сравнивалась текущая дата с завершением. Если текущая дата < Завершения, то возвращается к чтению.

 

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

 

Если мы получаем данные из "Автогенерируемой страницы", есть ли необходимость хранить данные об отпусках отдельно в срм.

Сначала попытайтесь понять, что вы вообще хотите сделать. Если задач ещё не существует, то Вы их не вычитаете и не измените.

 Если текущая дата < Завершения, то возвращается к чтению

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

_KSL_,

Если у Вас версия on-site Вы можете запустить SQL profiler и отследить запрос, который идет в базу, и понять, почему происходит зацикливание.

 

Покажите код, каким образом Вы реализовали, установку ответственных в задачах в Вашем бизнес-процессе.

Алла, он просто нарисовал в БП цикл, надеясь, что он будет постоянно до даты конца отпуска крутиться и обрабатывать появляющиеся задачи. Но так нельзя, количество повторений ограничено, а до того всё зависнет.

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

Ясно. Ну, ты же, знаешь, есть старая привычка докопаться до сути вопроса)))

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

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

Решал ли кто-то задачу смена типа результата активности? Поделитесь опытом.

Это цвет покраски кнопок результатов активности в задачах по БП.

Нравится

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

В справочнике Результат Активности, есть 3 категории.

В зависимости от того, какая категория указана, такой цвет кнопки и будет.

Нейтральный - серый

Отрицательный - красный

Успех - зеленый


 В коде зашиты только эти три цвета и это касается задач созданных через элемент Выполнить задачу в БП



Литвинко Павел,

это прозрачно.Может можешь подсказать где зашито?

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

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

Посмотрел параметр Process Item, но он не у всех процессных активностей заполнен

Нравится

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

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

Кстати, была такая идея от Вас же, только речь шла о правах, а не активностях.

И ещё похожая идея, только для определения записей, заведенных по OData.

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

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

А ещё есть задачи, созданные при элементах "Открыть страницу редактирования", созданные в DCM...



Думал, вдруг есть что-то встроенное уже

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

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

Здравствуйте. Столкнулся с проблемой следующего рода:

Появилась необходимость добавить действие на страницу редактирования активности.

Выполнил все пункты согласно инструкции на https://academy.terrasoft.ru/documents/technic-sdk/7-7/dobavlenie-deystviya-na-stranicu-redaktirovaniya . 

В результате получилась вот такая замещающая страница:

define("ActivityPageV2", ["ProcessModuleUtilities", "AbrConstants"],
    function(ProcessModuleUtilities, AbrConstants) {
        return {
            // Название схемы объекта страницы редактирования.
         entitySchemaName: "Activity",
         methods: {
          // Проверяет, в каком состоянии активность.
          isRunningMail: function() {
                if (this.get("Status") && this.get("Result")) {
                 return (this.get("Status").value === AbrConstants.Activity.State.Completed && this.get("Result").value === "632afdd2-f616-4ea6-87d2-8ed38eed8aff");
                }
                return false;
               },
            // Метод-обработчик действия.
          showActionInfo: function() {
                var args = {
                  sysProcessName: "SendEmailAboutTheApproval",
                  scope: this
                 };
                ProcessModuleUtilities.executeProcess(args);
                this.showInformationDialog("Оповещения в ДТ и ОД отправлены.");
               },
            // Переопределение базового виртуального метода, возвращающего коллекцию действий страницы редактирования.
          getActions: function() {
                // Вызывается родительская реализация метода для получения
                // коллекции проинициализированных действий базовой страницы.
                var actionMenuItems = this.callParent(arguments);
                // Добавление линии-разделителя.
                actionMenuItems.addItem(this.getButtonMenuItem({
                 Type: "Terrasoft.MenuSeparator",
                 Caption: ""
                }));
                // Добавление пункта меню в список действий страницы редактирования.
                actionMenuItems.addItem(this.getButtonMenuItem({
                    // Привязка заголовка пункта меню к локализуемой строке схемы.
                 "Caption": {bindTo: "Resources.Strings.SendEmailToOdAndDt"},
                    // Привязка метода-обработчика действия.
                 "Tag": "showActionInfo",
                    // Привязка свойства доступности пункта меню к значению, которое возвращает метод isRunning().
                 "Enabled": {bindTo: "isRunningMail"}
                }));
                return actionMenuItems;
               }
         }
        };
       }
);

Кнопка добавилась, но свойство "Enabled" работает некорректно.

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

Но, когда мы со страницы активностей открываем задачу, которая имеет состояние "Завершена" и результат "Выполнена", кнопка всегда неактивна и никак не реагирует на изменения состояния или результата.

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

Но если просто обновить страницу, кнопка становится активна.

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

В чем может быть причина?

Нравится

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

stique,

//PageV2
attributes: {
//На пейдже первым делом объявляю атрибут
//на который я буду биндить (байндить) свойство "enabled" кнопки
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляю сообщение с направлением PUBLISH, которое будем отправлять на секцию
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.PUBLISH
 }
},
methods: {
//Объявляю метод, который буду запускать два раза
//При инициализации страницы и после сохранения
//Он проставляет атрибут для кнопки 
//и одновременно отправляет сообщение с текущим статусом на секцию
//Хотя здесь можно сделать лучше и отправлять не статус, а непосредственно значение true/false
 getOrderButtonStatus: function() {
  this.sandbox.publish("GetOrderButtonStatus", this.get("UsrStatus"), [this.sandbox.id]);
  var status = this.$UsrStatus;
  if (status &amp;&amp; status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 },
 onEntityInitialized: function() {
  this.callParent(arguments);
//вызываем первый раз
  this.getOrderButtonStatus();
 },
 onSaved: function() {
  this.callParent(arguments);
//вызываем второй раз
  this.getOrderButtonStatus();
 }
},
diff: [
//У меня была обычная кнопка на карточке, у Вас в меню Действия
//Так что Вам нужно забиндить кнопку на атрибут в Вашем методе getActions()
 {
  "operation": "insert",
  "name": "creatingOrderButton",
  "values": {
   "itemType": 5,
   "caption": "Create order",
   "click": {
    "bindTo": "syncCreatingOrder"
   },
   "style": "green",
   "enabled": {
    "bindTo": "isOrderButtonEnabled"//забиндить на атрибут
   },
   "classes": {
    "textClass": "actions-button-margin-right"
   }
  },
  "parentName": "LeftContainer",
  "propertyName": "items",
  "index": 7
 }
]
 
 
 
 
 
//SectionV2
attributes: {
//Здесь объявляем такой же атрибут
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляем такое же сообщение с направлением SUBSCRIBE
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.SUBSCRIBE
 }
},
methods: {
//в init подписываемся на нужное нам сообщение
//и если оно к нам приходит - запускается метод getOrderStatusButton
//Опять таки, здесь можно и нужно логику переделать, чтобы получать сразу значение true/false
//вместо статуса
 init: function() {
  this.callParent(arguments);
  this.sandbox.subscribe("GetOrderButtonStatus", function(value) { this.getOrderButtonStatus(value); }, this, [this.getCardModuleSandboxId()]);
 },
 getOrderButtonStatus: function(status) {
  if (status &amp;&amp; status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 }
}

 

Насколько я понимаю и помню, то добавив действие на ActivityPageV2, это действие по-моему создается автоматически и в секции, средствами сообщений, я давно это тестил, уже не помню. В общем, в первом случае у вас кнопка ДЕЙСТВИЯ находится на ActivitySectionV2, а во втором случае кнопка ДЕЙСТВИЯ находится на ActivityPageV2, это две разные кнопки. И на пейдже у вас есть метод isRunningMail(), но на секции его нет. Вам нужно организовать передачу сообщения с пейджи на секцию какой там статус и результат, потому что на секции этой информации нет. У Вас случайно ошибки в консоль не сыпятся, когда вы открываете первый раз активность в совмещенном режиме? Я надеюсь, что хоть немного понятно изъяснился)) I'm doing my best)

Добавить комментарий

Alex Zaslavsky,

Нет, ошибок в консоли нет.

Может быть я путаю, но кажется, когда мы открываем задачу, ActivityPage сразу подгружается.

stique,

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

Вот попробуйте в секцию добавить метод isRunningMail() который всегда возвращает true, для примера, и кнопка у вас, скорее всего, заработает.

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

Добавить комментарий

Alex Zaslavsky,

Кажется Вы правы! Как правильно поступить в таком случае?

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

А где про этот механизм можно почитать? 

stique,

С механизмом сообщений знакомы? Sandbox

Я биндил свойство enabled на атрибут, на пейдже в методах onEntityInitialized и onSaved я отправлял сообщения на секшн и в зависимости от условий проставлял такой же атрибут в true или false.

Если нужно прям подробно, то могу позже описать полностью как я сделал.

Alex Zaslavsky,

Alex Zaslavsky пишет:

С механизмом сообщений знакомы? Sandbox

Увы нет, только неделю  как изучаю bpm)

Alex Zaslavsky пишет:

Если нужно прям подробно, то могу позже описать полностью как я сделал.

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

stique,

//PageV2
attributes: {
//На пейдже первым делом объявляю атрибут
//на который я буду биндить (байндить) свойство "enabled" кнопки
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляю сообщение с направлением PUBLISH, которое будем отправлять на секцию
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.PUBLISH
 }
},
methods: {
//Объявляю метод, который буду запускать два раза
//При инициализации страницы и после сохранения
//Он проставляет атрибут для кнопки 
//и одновременно отправляет сообщение с текущим статусом на секцию
//Хотя здесь можно сделать лучше и отправлять не статус, а непосредственно значение true/false
 getOrderButtonStatus: function() {
  this.sandbox.publish("GetOrderButtonStatus", this.get("UsrStatus"), [this.sandbox.id]);
  var status = this.$UsrStatus;
  if (status &amp;&amp; status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 },
 onEntityInitialized: function() {
  this.callParent(arguments);
//вызываем первый раз
  this.getOrderButtonStatus();
 },
 onSaved: function() {
  this.callParent(arguments);
//вызываем второй раз
  this.getOrderButtonStatus();
 }
},
diff: [
//У меня была обычная кнопка на карточке, у Вас в меню Действия
//Так что Вам нужно забиндить кнопку на атрибут в Вашем методе getActions()
 {
  "operation": "insert",
  "name": "creatingOrderButton",
  "values": {
   "itemType": 5,
   "caption": "Create order",
   "click": {
    "bindTo": "syncCreatingOrder"
   },
   "style": "green",
   "enabled": {
    "bindTo": "isOrderButtonEnabled"//забиндить на атрибут
   },
   "classes": {
    "textClass": "actions-button-margin-right"
   }
  },
  "parentName": "LeftContainer",
  "propertyName": "items",
  "index": 7
 }
]
 
 
 
 
 
//SectionV2
attributes: {
//Здесь объявляем такой же атрибут
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляем такое же сообщение с направлением SUBSCRIBE
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.SUBSCRIBE
 }
},
methods: {
//в init подписываемся на нужное нам сообщение
//и если оно к нам приходит - запускается метод getOrderStatusButton
//Опять таки, здесь можно и нужно логику переделать, чтобы получать сразу значение true/false
//вместо статуса
 init: function() {
  this.callParent(arguments);
  this.sandbox.subscribe("GetOrderButtonStatus", function(value) { this.getOrderButtonStatus(value); }, this, [this.getCardModuleSandboxId()]);
 },
 getOrderButtonStatus: function(status) {
  if (status &amp;&amp; status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 }
}

 

Alex Zaslavsky,

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

Еще нашел информацию что можно использовать "reloadAll: true", но пока не знаю как это прикрутить)

 

stique,

Отпишитесь потом, получилось или нет :)

Alex Zaslavsky,

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

stique,

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

Если Вам нужно другое поведение, то можно создать на пейдже атрибут, который будет реагировать на изменение полей "Результат" и "Статус" и отправлять сендбоксом сообщение в любой момент, при изменении этих полей. Но как по мне, это не совсем правильно. Но решать Вам)

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

Реализовал разделение календаря по сотрудникам в фильтре через кучу diff. Встал вопрос - как наполнить каждый разными данными?

По умолчанию activityCollection планировщика указан как ScheduleGridData. Соответственно, на каждый календарь на странице создаю ScheduleGridData0, ScheduleGridData1, ScheduleGridData2 и так далее и подставляю эти значения в каждый activityCollection, но календари становятся вообще пустыми. Я так понимаю, вопрос в методах отрисовки, но тогда придется переписывать половину CRM.

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

Вот пример одного из календарей

{
            "operation": "insert",
            "name": "Schedule0",
            "parentName": "DataViewsContainer",
            "propertyName": "items",
            "values": {
                 "id": "ActivitySectionV2Scheduler0",
                 "selectors": {"wrapEl": "#ActivitySectionV2Scheduler0"},
                 "itemType": Terrasoft.ViewItemType.SCHEDULE_EDIT,
                 "visible": {"bindTo": "isSchedulerVisible0"},
                 "startHour": Terrasoft.SysSettings.cachedSettings.SchedulerTimingStart,
                 "displayStartHour": Terrasoft.SysSettings.cachedSettings.SchedulerDisplayTimingStart + "-00",
                 "dueHour": Terrasoft.SysSettings.cachedSettings.SchedulerTimingEnd,
                 "timeScale": {"bindTo": "getTimeScale"},
                 "period": {"bindTo": "getSchedulerPeriod"},
                 "timezone": [{}],
                 "startDate": null,
                 "dueDate": null,
	         "activityCollection": {"bindTo": "ScheduleGridData0"},
                 "selectedItems": {"bindTo": "SelectedRows"},
                 "changeSelectedItems": {"bindTo": "onChangeSelectedItems"},
                 "scheduleItemDoubleClick": {"bindTo": "onScheduleItemDoubleClick"},
                 "scheduleItemTitleMouseOver": {"bindTo": "scheduleItemTitleMouseOver"},
                 "scheduleItemTitleClick": {"bindTo": "scheduleItemTitleClick"},
                 "change": {"bindTo": "changeScheduleItem"},
                 "selection": {"bindTo": "SchedulerSelection"},
                 "floatingItemsCollection": {"bindTo": "SchedulerFloatItemsCollection"},
                 "selectionKeyPress": {bindTo: "onSelectionKeyPress"},
                 "floatingItemReady": {"bindTo": "onFloatingItemReady"},
                 "selectionKeyPressSymbols": {"bindTo": "SchedulerSelectionPressedKeys"},
                 "itemBindingConfig": {
                     "itemId": {"bindTo": "Id"},
                     "title": {"bindTo": "getScheduleItemTitle"},
                     "changeTitle": {"bindTo": "onTitleChanged"},
                     "startDate": {"bindTo": "StartDate"},
                     "changeStartDate": {"bindTo": "onStartDateChanged"},
                     "dueDate": {"bindTo": "DueDate"},
                     "changeDueDate": {"bindTo": "onDueDateChanged"},
                     "status": {"bindTo": "getScheduleItemStatus"},
                     "changeStatus": {"bindTo": "onStatusChanged"},
                     "background": {"bindTo": "Background"},
                     "fontColor": {"bindTo": "FontColor"},
                     "isBold": {"bindTo": "IsBold"},
                     "isItalic": {"bindTo": "IsItalic"},
                     "isUnderline": {"bindTo": "IsUnderline"},
                     "markerValue": {"bindTo": "getScheduleItemHint"}
                   },
                   "floatingItemBindingConfig": {
                        "caption": {"bindTo": "getSimpleModuleCaption"},
                        "width": {"bindTo": "getSimpleModuleWidth"}
                   }
}

 

Нравится

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

Смотрите, как реализовано расписание для нескольких пользователей в дополнении «Advanced schedule for bpm'online». 

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

Добрый день. 

Не все оповещения уходят пользователям, активность тип email, остаются в черновиках в состоянии "Не отправлено", приходится отправлять вручную. Как установить причину ? Или как отправить "разом" все оповещения за день, нету возможности выбора всех писем. Сама почта работает стабильно, проверяли. Прошу помочь.

Прикрепленные файлы

Нравится

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

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

Как происходит отправка уведомлений и проблема касается только уведомлений или и других почтовsых сообщений? Скорее всего есть БПР который отправляет уведомления, проверьте какой тип отправки указан в нем, ручная отправка или автоматическая?

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

Как происходит отправка уведомлений и проблема касается только уведомлений или и других почтовsых сообщений? Скорее всего есть БПР который отправляет уведомления, проверьте какой тип отправки указан в нем, ручная отправка или автоматическая?

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

Добрый день!



Возможно кто-нибудь ранее сталкивался с проблемами в мобильном приложении на iOS. Приложение постоянно намертво зависает при создании/редактировании активностей. Очистка кэша помогает ровно до первого раза. Пользователи устройств на android таких проблем не испытывают. С интернетом и свободным пространством на телефоне проблем нет.

Десктопная версия BPM 7.12, мобильная 7.13.

Чем могут быть вызваны проблемы в мобильном приложении на iOS? Может ли кто-нибудь посоветовать метод борьбы с данными проблемами? 

Нравится

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

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



По поводу диагностирования самих причин:

Если ошибка возникает только на мобильном приложении (в то время, как на веб-версии все отрабатывает нормально), тогда необходимо понимать какие действия выполняются в системе и приводят к ошибке. Информация об ошибках хранится мобильном устройстве.





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

  • версия ОС системы
  • действия, которые выполняются в системе перед началом проблем (к примеру, в какие разделы мобильного приложения переходили, какие записи в разделе активностей редактировали)
  • логи приложения (в них можно найти сообщения о возможных ошибках, которые повлияли на проседание производительности)

Мотков Илья,

Спасибо за ответ!

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

Добрый день!

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

Нравится

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

По умолчанию при добавлении фильтра по колонке «Дата/Время» не учитывается время. Необходимо в параметрах элемента «Читать данные» дополнительно проставлять признак «Учитывать время в фильтре» (изначально стоит false).

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