Фильтры

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

Тогда из БП приходится посылать message, прописывать методы его обработки на странице и т.п.

Можно это сделать универсально, создав User task, указав в нём элемент для обновления (деталь или поле), а также новое значение для поля? А дальше уже базовые механизмы выполнят всё, что нужно на странице

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

Это было бы супер!)

Владимир, уже давно заведена идея, чтобы это происходило автоматически: «Данные, которые изменяются при выполнении бизнес-процесса, не актуализируются/обновляются на странице редактирования, если пользователь в текущий момент находится на ней». Она принята, но пока не реализовывалась. Зафиксировал и в том виде, как предлагаете Вы, чтобы обновлять принудительным запуском действия. Спасибо за идею!

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

Реализовать возможность полностью отключить возможность добавления новых записей через "Создать" в справочном поле

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

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

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

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

 

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

И самое интересное, что в некоторых полях этой возможности нет (очевидно, настраивается каждое поле  карточки отдельно). Но не делать же это в каждом справочном поле по всей системе отдельно!

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

Если поле заведено как справочник, то пункт создать появляется. Если как список, то такого пункта нет. Возможность создания зависит от наличия страницы редактирования записи. Если у справочника, например, отрасль нет страницы редактирования, то система выдаст ошибку, что новые значения можно заводить через справочник. Если страница редактирования есть, то далее вступает в силу проверка на наличие полномочий. Для справочников это наличие полномочий на операцию CanManageLookups. Для полей, ссылающихся на разделы - это полномочия на операцию создать в объекте. Итого отвечая на ваш вопрос. Никак. Если у пользователя есть полномочия на создание записей в объекте, то он может его создать как через раздел, так и через пункт Создать в справочном поле. Как вариант можно настроить попробовать поиск дублей на требуемые разделы. Поиск дублей можно настроить на все разделы, где включен глобальный поиск.

Алексей Следь пишет:
Итого отвечая на ваш вопрос. Никак.

Это не вопрос, а идея. У нас все клиенты просят запретить эту возможность. До 7.13 это довольно легко решалось замещением модуля LookupQuickAddMixin.  
Но теперь этот путь замещения запретили, стало намного сложнее

Потому предлагаю вынести это в системную настройку. 

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

то, что это идея, я заметил только после того как ответил))))

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

Алексей Следь пишет:
Например у меня пользователи очень просят дать им возможность самим заполнять справочник должностей

Ох, это отдельная проблема, что CanManageLookup - слишком неконфигурируемая вещь. Разные lookup'ы иногда нужно давать под управление разным ролям. 

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

Владимир Соколов пишет:
Ох, это отдельная проблема

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

Алексей Следь пишет:
отключен стандартный механизм проверки полномочий

Интересно! А как вы отключаете стандартный механизм проверки? 

Но этот обход вам не добавил нужную функцию "создать"?

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

 

По ответам:

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

Ещё зарегистрирована такая сложность в использовании функциональности: «Система не выдает никакого предупреждения если в справочниках создать значения с одинаковым именем.»

 

До 7.13 это довольно легко решалось замещением модуля LookupQuickAddMixin.  
Но теперь этот путь замещения запретили, стало намного сложнее

Сейчас тоже можно, я тут вчера написал. 

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

Такую идею зафиксировали ранее, см. комментарии тут.

Интересно! А как вы отключаете стандартный механизм проверки? 

См. мой ответ тут

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

Функционал по построению сводных таблиц пришелся очень кстати, но вот ему еще не хватает возможности просматривать из чего получились итоги. Например, раздел обращения. Сводная таблица по просроченным обращениям, на стадиях в разрезе контрагентов. И вот нашим пользователям очень не хватает возможности провалиться в исходные данные. Показать те 2 обращения, которые попали в отчет. Как это делает Excel если дважды кликнуть на итоги в сводной таблице

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

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

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

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

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

 

Подскажите корректно ли работает деталь "Участники" в следующем кейсе:

Шаг1. При создании задачи автор указывает в поле "Ответственный" значение "Исполнитель1". В результате Система автоматически добавляет в деталь "Участники" запись с "Исполнителем1"

Шаг2. Автор заменяет в поле "Ответственный" значение "Исполнитель1". В результате Система автоматически добавляет в деталь "Участники" запись с "Исполнителем2" (удаляя "Исполнителя1") и "Автора"

---------------------------------------------------------------------

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

либо автора задачи Система сразу добавляет в участники, либо никогда (только вручную или через созданный БП).

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

 

//подскажите куда надо смотреть, чтобы настроить кейс:

- автор при создании задачи добавляется в деталь "Участники"

либо

- автор при изменении ответственного не добавляется в деталь "Участники"

 

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

Обратите внимание, что там ещё разная роль (видно, если вытянуть колонку):

Логика реализована во встроенном БП объекта Activity пакета Base:

  public virtual void AddActivityParticipantToInsertedValues(Guid participantId, Dictionary<string, object> participantParams, bool overrideExistingParticipant) {
   var insertedValues = (InsertedValues as Dictionary<Guid, object>) ?? new Dictionary<Guid, object>();
   InsertedValues = insertedValues;
   if (overrideExistingParticipant || !insertedValues.ContainsKey(participantId)) {
    insertedValues[participantId] = participantParams;
   }
  }
 
  public virtual bool OnActivitySaved(ProcessExecutingContext context) {
   SetActivityParticipantRightsOnSaved();
   string typeColumnValueName = Entity.Schema.Columns.FindByName("Type").ColumnValueName;
   Guid typeId = Entity.GetTypedColumnValue<Guid>(typeColumnValueName);
      if (typeId == Terrasoft.Configuration.ActivityConsts.EmailTypeUId) {
       InitializeEmailParticipantHelper().InitializeParameters(Entity);
       AutoEmailRelationProceed();
       InitializeEmailParticipantHelper().SetEmailParticipants();
      } else {
       UpdateParticipantsByOwnerContact();
       SynchronizeActivityOnSaved();
       AutoEmailRelationProceed();
       CreateActivityParticipantsFromInsertedValues();
      }
      return true;
  }
...
  public virtual void RemoveEmailParticipants() {
   var recepientEmails = RecepientsEmailsForDelete as List<string>;
   if ((recepientEmails != null) && (recepientEmails.Count > 0)) {
    var queryParameters = recepientEmails.Select(item => new QueryParameter(item)).ToList();
    new Delete(UserConnection)
     .From("ActivityParticipant")
     .Where("ActivityId").IsEqual(Column.Parameter(Entity.PrimaryColumnValue))
     .And("ParticipantId").In(
      new Select(UserConnection)
       .Column("Id")
       .From("Contact")
       .Where("Email").In(queryParameters)).Execute();
   }
  }
  public virtual void UpdateParticipantsByOwnerContact() {
   DeleteOldOwnerAndContactParticipants();
   var participantRoles = ActivityUtils.GetParticipantsRoles(UserConnection);
   if ((newOwnerId != oldOwnerId) && (newOwnerId != Guid.Empty) && (newOwnerId != SenderId)) {
    AddActivityParticipantToInsertedValues(
     newOwnerId, 
     new Dictionary<string, object> {
      {"RoleId", participantRoles["Responsible"]}
     },
     true
    );
    if (oldOwnerId != Guid.Empty) {
     var authorColumn = Entity.Schema.Columns.FindByName("Author");
     if (authorColumn != null) {
      var authorId = Entity.GetTypedColumnValue<Guid>(authorColumn.ColumnValueName);
      AddActivityParticipantToInsertedValues(
       authorId, 
       new Dictionary<string, object> {
        {"RoleId", participantRoles["Participant"]}
       }, 
       false
      );
     }
    }
   }
   if ((newContactId != oldContactId) && (newContactId != Guid.Empty) && (newContactId != newOwnerId) && (newContactId != SenderId)) {
    AddActivityParticipantToInsertedValues(
     newContactId,
     new Dictionary<string, object> {
      {"RoleId", participantRoles["Participant"]}
     },
     false
    );
   }
  }

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

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

Спасибо за ответ, то что нужно (+ отдельное спасибо за то, что обрати внимание на роль).

Еще остался вопрос, - все таки это корректная работа, что автор при создании задачи участников в деталь не добавляется, но добавляется только после изменения значения в поле "Ответственный"? Какой бизнес-смысл такого базового поведения Системы (я бы даже сказал не очевидного)

 

+ влияет ли роль "Участник" и "Ответственный" на какие либо процессы? На сколько я успел протестировать - нет.

По том, как надо правильнее, уточняю.

Посмотреть все места, где используется объект справочника ParticipantRole, можно выборкой по тексту C# и JS-схем.

select *, cast(source as varchar(max)) from sysschemasource where source like '%participantRole%'
select *, cast(content as varchar(max)), (select name from sysschema where id = [SysSchemaId]) from sysschemacontent where content like '%participantRole%'


Как минимум, в Activity пакета Exchange для синхронизации встреч тоже добавляют именно «Участник»:

  public virtual void SynchronizeParticipants() {
   if (string.IsNullOrEmpty(Entity.Sender) && string.IsNullOrEmpty(Entity.Recepient)) {
    return;
   }
   if (Entity.GetTypedColumnValue<Guid>("ActivityCategoryId") == ExchangeConsts.ActivityMeetingCategoryId) {
    var recepientsEmails = (List<string>)RecepientsEmails;
    Dictionary<Guid, string> contactDictionary = ContactUtilities.GetContactsByEmails(UserConnection, recepientsEmails);
    if (contactDictionary.Count > 0) {
     var participantRoles = ActivityUtils.GetParticipantsRoles(UserConnection);
     foreach (var contactId in contactDictionary.Keys) {
      AddActivityParticipantToInsertedValues(
       contactId,
       new Dictionary<string, object> {
        {"RoleId", participantRoles["Participant"]}
       },
       false
      );
     }
     var insertedValues = InsertedValues as Dictionary<Guid, object>;
     if (insertedValues != null) {
      UpdateContactAndAccountByParticipant(insertedValues.Keys.ToList());
     }
    }
    Entity.SetColumnValue("Sender", string.Empty);
    Entity.SetColumnValue("Recepient", string.Empty);
   }
  }

Но это вставка, а не считывание.

 

Ещё константы ролей для писем используется в CommunicationPanelEmailSchema в условии  фильтрации входящих/исходящих:

/**
 * Adds requested email type filters.
 * @private
 * @param {Terrasoft.FilterGroup} filters Emails query filters.
 * @param {Terrasoft.EntitySchemaQuery} esq Emails query.
 */
_addFilterByEmailType: function(filters, esq) {
	var roleColumn = "Role";
	var emailType = this.get("EmailType");
	if (!this.getIsFeatureEnabled("SharedMailboxes") || emailType === EmailConstants.emailType.DRAFT) {
		var currentUserContact = Terrasoft.SysValue.CURRENT_USER_CONTACT.value;
		filters.add("currentContactFilter", this.Terrasoft.createColumnFilterWithParameter(
				Terrasoft.ComparisonType.EQUAL, "Owner", currentUserContact));
	}
	var participantRoles = ConfigurationConstants.Activity.ParticipantRole;
	switch (emailType) {
		case EmailConstants.emailType.INCOMING:
			this._addIncomingFilter(filters, roleColumn, [
				participantRoles.To, participantRoles.CC,
				participantRoles.BCC
			]);
			break;
		case EmailConstants.emailType.OUTGOING:
			this._addOutgoingFilter(filters, roleColumn, [participantRoles.From]);
			break;
		case EmailConstants.emailType.DRAFT:
			this._addDraftFilter(filters);
			break;
		default:
			break;
	}
},

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

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

Спасибо, за подробный ответ. Буду ждать от вас информацию по уточнению.

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

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

Сейчас в системе можно администрировать полномочия только от объектов.

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

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

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

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

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

Спасибо, что делаете наши продукты лучше!

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