Какие есть способы перенести все схемы из Custom в другой пакет?

Можно ли переименовать пакет "Custom" и создать свой?

или в SQL перенести все схемы в другой пакет?

Нравится

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

Каким образом можно динамически устанавливать интервалы для виджета "Шкала" на странице? 
Например, в зависимости от клиента (его предыдущей истории покупок) должны рассчитываться его интервалы (красный, желтый, зелёный)

Нравится

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

Владимир, существующая реализация компонента Gauge отображает изменения только цифры в центре, а 4 других параметра, означающие границы цветов, задаются в настройках и хранятся в json-конфиге в SysDashboard:

   "Gauge":{
      "parameters":{
         "caption":"Closed cases",
         "entitySchemaName":"Case",
         "filterData":"{\"className\":\"Terrasoft.FilterGroup\",\"items\":{\"12f77c73-1263-4d79-b397-8f55e2f8653e\":{\"className\":\"Terrasoft.CompareFilter\",\"filterType\":1,\"comparisonType\":3,\"isEnabled\":true,\"trimDateTimeParameterToDate\":false,\"leftExpression\":{\"className\":\"Terrasoft.ColumnExpression\",\"expressionType\":0,\"columnPath\":\"Status.IsFinal\"},\"isAggregative\":false,\"key\":\"12f77c73-1263-4d79-b397-8f55e2f8653e\",\"dataValueType\":12,\"leftExpressionCaption\":\"Status.Status is final\",\"rightExpression\":{\"className\":\"Terrasoft.ParameterExpression\",\"expressionType\":2,\"parameter\":{\"className\":\"Terrasoft.Parameter\",\"dataValueType\":12,\"value\":true}}}},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6,\"rootSchemaName\":\"Case\",\"key\":\"\"}",
         "aggregationType":1,
         "style":"widget-navy",
         "orderDirection":1,
         "min":0,
         "middleFrom":5,
         "middleTo":8,
         "max":10
      },
      "widgetType":"Gauge"
   }

А в GaugeDashboardItemData с ними работают:

 

		/// <summary>
		/// Returns data for indicator dashboard item.
		/// </summary>
		public override JObject GetJson() {
			JObject itemObject = base.GetJson();
			CopyProperties(itemObject);
			if (string.IsNullOrEmpty(GetSchemaName())) {
				return itemObject;
			}
			GaugeDashboardItemSelectBuilder selectBuilder = GetSelectBuilder();
			object value = GetData(selectBuilder);
			itemObject["dataValueType"] = selectBuilder.ColumnDataValueType;
			itemObject.Add(new JProperty("data", value));
			itemObject["min"] = Parameters.Value<int?>("min");
			itemObject["middleFrom"] = Parameters.Value<int?>("middleFrom");
			itemObject["middleTo"] = Parameters.Value<int?>("middleTo");
			itemObject["max"] = Parameters.Value<int?>("max");
			itemObject["orderDirection"] = Parameters.Value<int?>("orderDirection");
			return itemObject;
		}

То есть Вам надо будет делать свои аналоги GaugeDashboardItemData, GaugeModule (отображение в итогах), GaugeDesigner (окно настроек), где с ними работают, Возможно, понадобится ещё что-то изменить или просто скопировать с другим названием GaugeChartJsConfigBuilder.

node button icon

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

Можно ли каким-то образом не создавать новые значения справочников при импорте данных?

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

Нравится

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

Доброе утро, Владимир!

 

Есть такой, не до конца протестированный, вариант:

- забрать права доступа на операцию "Создание" для юзеров/ролей в объекте "Справочник": https://prnt.sc/wljjrd. Это относится только к справочникам, т.е. тем объектам у кого родителем является "Базовый справочник". Ни поле "Контакт", ни "Контрагент" под эти правила уже не подойдут.

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

 

Вариант нужно протестировать. У меня вышло так, что была лишь одна запись продажи, созданная Supervisor. Под тестовым юзером я, учитывая правила поиска дубля, залила файл и у меня создалась совершенно новая запись продажи с предзаполненными значениями, как и в файле. Плюс, что в справочниках не создались новые значения. Минус, наверное, в том, что стоило попробовать вытянуть Id продажи и учитывать его в правилах дублей.

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

 

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

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

В файле импорта указан тип контакта “клиент”.
В справочнике [ Типы контактов ] содержится значение “Клиент”.

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

В файле импорта указан тип контакта “«Клиент»”.
В справочнике [ Типы контактов ] содержится значение “Клиент”.

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

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

А как насчёт чистки данных перед импортом?) 

Или после, уже в базе. Или в момент, созданием своего специализированного механизма импорта, учитывающего все специальные случаи. До определённой версии была возможность запустить старое окно импорта с большим числом настроек, но в современных, где нет логики на основе 5.Х, такого, видимо, не выйдет.

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

Добрый день!

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

 

Например:
1. Счёт
     1.1. Категория продукта 1
         1.1.1. Продукт 1
         1.1.2. Продукт 2
     1.2 Категория продукта 2
         1.2.1. Продукт 3
         1.2.2. Продукт 4

Категория печатается нормально, а вот затем в каждой категории печатается весь набор продуктов (от 1-4) без привязки к предыдущему уровню (категории)

Нравится

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

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

Или не view, а записи в специальной таблице, наполняемой программно для каждого построения отчёта.

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

View не годится, так как у разных уровней разное форматирование в Word'e.

Как я понимаю, тогда только в Fast report?

Либо чисто программно формировать в скрипте документ Word с каким угодно форматированием при помощи библиотеки  DocumentFormat.OpenXml.dll, которая загружена в систему и используется и в стандартных схемах ReportService, WordReportingDesignWorker, WordReportUtility и WordReportGenerator.

Но перед этим проверьте в маркете существующие движки отчётов, нет ли там такого формата, который Вам нужен.

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

Как настроить зависимость между справочниками. 
Пример: Есть два справочника 

- Область

- Район 

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

Нравится

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

1. Добавьте зависимость в атрибут схемы.

2. Добавьте фильтрацию к справочному полю.

1. Добавьте зависимость в атрибут схемы.

2. Добавьте фильтрацию к справочному полю.

Дамиан Викторович пишет:

1. Добавьте зависимость в атрибут схемы.

2. Добавьте фильтрацию к справочному полю.

Возможно есть другое решение?

Артём, можно настроить бизнес-правило пользовательскими средствами или средствами разработки.

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

Добрый день!

Перед мной стоит такая задача. Нужно в бизнес-процессе, который запускается периодически (раз в 10 минут), получать список Обращений (Case) по определенному критерию и затем по каждому такому Обращению отправлять письмо. Я читал, что можно сформировать список объектов и передать его каким-то образом в бизнес-процесс, который обрабатывал бы этот список и отправлял письма. К сожалению, не могу найти примеров такого решения. Возможно, кто-то может дать ссылку на описание подобного варианта? Или же есть более удобные способы решения такой задачи? Заранее спасибо за ответ.

Нравится

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

Добрый день.

 

Посмотрите описание решения подобной задачи в статье по работе с коллекциями.

Добрый день.

 

Посмотрите описание решения подобной задачи в статье по работе с коллекциями.

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

 Большое спасибо за Ваш ответ. Очень полезная ссылка.

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

Добрый день!

У меня стоит задача обработки событий изменения некоторых реквизитов (Категория, Сервисный договор, Сервис) сущности Case (Обращения). Я могу в  событийном процессе обрабатывать события "Перед сохранением записи", "После сохранения записи", но я не совсем понимаю, как реализовать реакцию именно на изменение некоторых реквизитов. Т.е. если произошла запись, но перечисленные выше реквизиты не изменились, то ничего делать не нужно. Логика подсказывает, что нужно иметь "снимок" объекта до сохранения и сравнить его с значениями после. Как же это сделать? Заранее спасибо за помощь.

Нравится

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

На событие CaseSaving получаете в параметр старое значение поля:
 

AccountOldId = Entity.GetTypedOldColumnValue<Guid>("AccountId");
return true;

 

На событие CasеSaved уже можно сравнивать полученный параметр с новым значением
 

var NameEntity = new Entity(Entity);
if (NameEntity.FetchFromDB(Entity.PrimaryColumnValue)) {
	Guid accountId = NameEntity.GetTypedColumnValue<Guid>("AccountId");
 
	if ((AccountOldId != accountId)  { 
               ....
    }
 
}
return true;

 

Смотрите в сторону объекта Case пакета Case. на событие CaseSaving. Так же есть метод в процессе IsStatusChanged. 

 

Еще очень поможет методы событийного процесса объекта Case пакета SLM. Событие так же CaseSaving. Метод GetIsNeedToLogLifecycle() и GetLoggingColumns(). В последнем определяется на какие колонки пишется жизненный цикл обработки обращения. По аналогии я сделал свой журнал обработки обращения со своими колонками.

На событие CaseSaving получаете в параметр старое значение поля:
 

AccountOldId = Entity.GetTypedOldColumnValue<Guid>("AccountId");
return true;

 

На событие CasеSaved уже можно сравнивать полученный параметр с новым значением
 

var NameEntity = new Entity(Entity);
if (NameEntity.FetchFromDB(Entity.PrimaryColumnValue)) {
	Guid accountId = NameEntity.GetTypedColumnValue<Guid>("AccountId");
 
	if ((AccountOldId != accountId)  { 
               ....
    }
 
}
return true;

 

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

 Большое спасибо за Ваш ответ. Буду разбираться.

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

 Большое спасибо за Ваш ответ. Буду разбираться.

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

Добрый день!

Периодически возникают задачи для реализации их в системе.

Ищу людей, заинтересованных в сдельной работе.

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

Нравится

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

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

Нравится

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

Добрый день!

У нас это реализовано следующим образом:

Забираем у всех права на просмотр лидов. Если необходимо чтобы какая то роль или оргединица имела права на просмотр/редактирование/удаление лидов настраиваем штатно. Создали 2 бизнес-процесса, первый срабатывает при создании лида, второй при смене ответственного в лиде. В этих БП регулируются права на лид.

Добрый день!

У нас это реализовано следующим образом:

Забираем у всех права на просмотр лидов. Если необходимо чтобы какая то роль или оргединица имела права на просмотр/редактирование/удаление лидов настраиваем штатно. Создали 2 бизнес-процесса, первый срабатывает при создании лида, второй при смене ответственного в лиде. В этих БП регулируются права на лид.

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

В Operation permissions создаём операцию CanReadLead и добавляем в неё роли. Затем в том же БП выдаём этим ролям права на чтение лидов.

И не забываем про права на редактирование.

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

gif_section_object_permissions_select_groups.gif

Зверев Александр пишет:
то на новые записи будет получать права только автор и ответственный

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

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

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

Добрый день!

 

Я удаляю письмо (Активность типа Email) из стандартного БП, созданного в дизайнере бизнес процессов. 

 

Есть ли возможность из БП обновить коммуникационную панель? Сейчас письмо из неё пропадает только после обновления страницы. 

Нравится

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

Да. Сам так делаю примерно таким методом в схеме CommunicationPanelEmailSchema, а из БП шлю сообщение соответствующее:

onMyBpFinish: function(scope, message) {
    if (!message || message.Header.Sender !== "UpdateEmailHistory") {
        return;
    }
    var ID = message.Body;
    var collection = this.get("EmailCollection");
    var foundItem = collection.collection.items.find(item => item.id === ID);
    foundItem.set("IsNeedReload", false);
    this.reloadEmailsData([ID]);
    collection.remove(foundItem);
}

Скрипт в конце БП: 

var userConnection = Get<UserConnection>("UserConnection");
var EmailID = Get<string>("EmID");
EmailID.ToString();
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(UserConnection,"UpdateEmailHistory", EmailID);
return true;

Возможно, можно как-то красивее и изящней, но вроде этот метод работает и наша ТП довольна результатом

Да. Сам так делаю примерно таким методом в схеме CommunicationPanelEmailSchema, а из БП шлю сообщение соответствующее:

onMyBpFinish: function(scope, message) {
    if (!message || message.Header.Sender !== "UpdateEmailHistory") {
        return;
    }
    var ID = message.Body;
    var collection = this.get("EmailCollection");
    var foundItem = collection.collection.items.find(item => item.id === ID);
    foundItem.set("IsNeedReload", false);
    this.reloadEmailsData([ID]);
    collection.remove(foundItem);
}

Скрипт в конце БП: 

var userConnection = Get<UserConnection>("UserConnection");
var EmailID = Get<string>("EmID");
EmailID.ToString();
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(UserConnection,"UpdateEmailHistory", EmailID);
return true;

Возможно, можно как-то красивее и изящней, но вроде этот метод работает и наша ТП довольна результатом

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