Добрый день.

 

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

Но выходит ошибка "Текущий пользователь не имеет прав на запуск администрируемой операции с кодом "CanManageLookups".

Как можно решить данную проблему?

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

 

Нравится

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

Вариант 1. 

1. Зайдите в   Управление конфигурации - Права доступа на операции - 
2. Найдите операцию с кодом "CanManageLookups"
3. Добавьте нужному пользователю или роли права на эту операцию.
Вариант 2. 
Для объекта справочника измените Родительский объект на "Базовый объект", а не "Базовый справочник" и опубликуйте (при этом слетят базовые поля Name и Description)
 

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

Пробую использовать createInFilter. При дебаге четко вижу, что filteredAgreementsKeys это массив из двух Id. Однако фильтр не отрабатывает и ошибок в консоль не сыпется. Кто нибудь использовал in-Filter в конфигурационных схемах при открытии справочника?

openAgreementsLookup: function (filteredAgreementsKeys, scope) {
					debugger;
					var filterCollection = Terrasoft.createFilterGroup();
					var filter = Terrasoft.createInFilter("Id", filteredAgreementsKeys);
					filter.Name = "filter";
					filterCollection.add("filter", filter);
					var config = {
						entitySchemaName: "IDSBAgreement",
						multiSelect: true,
						columns: ["IDSBName", "IDSBPartnerCode"],
						filters: filterCollection
					};

					scope.openLookup(config, function (args) {
						scope.addCallBack(args, scope);
					}, scope);
				}

 

Нравится

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

поменял 

createInFilter на

createColumnInFilterWithParameters и всё заработало

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

Неоднократно задавал тут вопрос: возможно ли применить функционал расширенного фильтра к объекту "справочник".

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

на самом деле мне удалось этого добиться, правда не совсем стандартным способом...

  1. Создал раздел внутренними механизмами BPM
  2. Дропнул тейбл раздела в БД
  3. Создал представление (с inner join из 2 таблиц) с таким же названием в БД из п.2.
  4. Внес изменения в объект в БПМ - создал columns точь-в-точь как в представлении + установил признак "представление БД" (!)
  5. Закастомил страницу реестра.

Правда теперь не понимаю может ли эти изменения как-то негативно повлиять на работу приложения в целом?

Нравится

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

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

Только обычно создают в обратном порядке: сначала — схему с установленной галкой, потом — view в базе с такими же полями. Таблицы при этом не создаётся.

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

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

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

ключевое слово - расширенный фильтр.

К справочнику его не применить.

Соответственно создал раздел, (руками его создавать - неблагодарное дело). А уже потом ахалай-махалай с Vw...

Случайно обнаружил: подобное действие с разделом привело к ошибке (см. принт-скрин).

  УРЛ https://[url_app]/0/ServiceModel/EntityDataService.svc/ для меня крайне важен...

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

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

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

Возник следующий вопрос.

Необходимо в реестр справочника, например Статусы обращения, вывести значения колонки IsFinal аналогично методу setSubtitleColumns согласно SDK

https://academy.terrasoft.ru/documents/technic-sdkmob/7-12/sdk-reestra

В коробочном решении грид справочника выглядит следующим образом:

 

 

 

 

 

Пример необходимой реализации, колонка контакт:

 

 

 

 

 

 

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

Попытки задания Subtitle через дополнительный модуль, подключённый в манифесте для раздела Case, не дал результата. Что-то делаю не так.

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

Спасибо!

 

Нравится

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

Примеры использования этого свойства есть в «коробке» в схемах MobileLookupGridPageConfig, MobileLookupGridOpportunityPageConfig, MobileCaseMessageHistoryModuleConfig и MobileCaseMessageHistoryModuleConfig. Судя по названию, вторая схема как раз может использоваться для окна выбора из справочника. Её код:

Terrasoft.sdk.LookupGridPage.setSubtitleColumns("Opportunity", ["Account"]);

 

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

Добрый день!

Суть такова. В системе есть справочник в который занесены номера недель и соответствующие им календарные даты. (Например: Номер недели: 3; Дата: 14.01.2019 - 18.01.2019). 

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

Нравится

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

Возможность есть 

1 БП запускайте по расписанию

2 С помощью элемента формула можно получить номер текущей неделе дальше обновить или что вам нужно сделать с этой записью

По работе в формуле с датами более подробно смотри тут

Возможность есть 

1 БП запускайте по расписанию

2 С помощью элемента формула можно получить номер текущей неделе дальше обновить или что вам нужно сделать с этой записью

По работе в формуле с датами более подробно смотри тут

Накидал на C# скрипт, который выдает список с данными (неделя, начало, конец, год). осталось вызывать раз в год

var data = WeekWorker.GetYearWeekData(2019);

и данные парсить в справочник

using System;
using System.Collections.Generic;
using System.Globalization;
 
namespace TestApp
{
    public class WeekData
    {
        public int year { get; set; }
        public int week { get; set; }
        public DateTime weekStart { get; set; }
        public DateTime weekEnd { get; set; }
    }
 
    public class WeekWorker
    {
        public static List<WeekData> GetYearWeekData(int year)
        {
            var weeksdata = new List<WeekData>();
 
            int weeks = GetWeeksInYear(year);
            for (int i = 1; i <= weeks; i++)
            {
                var firstDay = FirstDateOfWeekISO8601(year, i);
                var lastDay = firstDay.AddDays(6);
 
                weeksdata.Add(new WeekData() { year = year, week = i, weekStart = firstDay, weekEnd = lastDay });
            }
 
            return weeksdata;
        }
        public static int GetWeeksInYear(int year)
        {
            DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
            DateTime date1 = new DateTime(year, 12, 31);
            Calendar cal = dfi.Calendar;
            int weeks = cal.GetWeekOfYear(date1, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
            return weeks;
        }
 
        public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
        {
            DateTime jan1 = new DateTime(year, 1, 1);
            int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
 
            // Use first Thursday in January to get first week of the year as
            // it will never be in Week 52/53
            DateTime firstThursday = jan1.AddDays(daysOffset);
            var cal = CultureInfo.CurrentCulture.Calendar;
            int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
 
            var weekNum = weekOfYear;
            // As we're adding days to a date in Week 1,
            // we need to subtract 1 in order to get the right date for week #1
            if (firstWeek == 1)
            {
                weekNum -= 1;
            }
 
            // Using the first Thursday as starting week ensures that we are starting in the right year
            // then we add number of weeks multiplied with days
            var result = firstThursday.AddDays(weekNum * 7);
 
            // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601
            return result.AddDays(-3);
        }
    }
 
}

 

Григорий Чех пишет:

Возможность есть 

1 БП запускайте по расписанию

2 С помощью элемента формула можно получить номер текущей неделе дальше обновить или что вам нужно сделать с этой записью

По работе в формуле с датами более подробно смотри тут

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

Все доступные в дизайнере элементы процесса описаны в руководстве.

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

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

Зверев Александр пишет:

Все доступные в дизайнере элементы процесса описаны в руководстве.

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

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

Поделились же, в первом и втором комментарии.

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

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

Пытаюсь в коде сбросить справочник

this.set("UsrDealerAccount", {value: null, displayValue: null});

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

Если поставить на нее курсор и нажать BackSpace, то тогда всё правильно - не дает сохранить.

Что я делаю не так?

Нравится

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

Вы в справочное поле вставляет "Пустой объект", поэтому в вашем случае с точки зрения валидатора поле заполнено.
Делайте так: 

this.set("UsrDealerAccount", null);

Литвинко Павел,Там потом ошибки в консоли валятся

Алексей-Карягин пишет:

Литвинко Павел,Там потом ошибки в консоли валятся

В каком случае и какие ошибки? 

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

у меня фильтрация этого поля правилом, когда туда плюхаешь нул, он ругается на этот нул.

Алексей-Карягин пишет:

Попробуйте тогда, вместо null использовать  Terrasoft.GUID_EMPTY может поможет

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

к сожалению, нет

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

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

Добрый день!

Никто не сталкивался с задачей, что нужно настроить доступ к отдельным записям справочника? (например есть справочник "Специальность" и часть записей в нём нужно скрыть от пользователей определённой функц. роли)

Нравится

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

А такая же настройка доступа к объекту по записям не работает?

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

А такая же настройка доступа к объекту по записям не работает?

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

Да, для объекта справочника можно так же включить администрирование по записям, как и для другой таблицы. При этом автоматически в базе должна создаться таблица Sys...Right. Поскольку справочник не зарегистрирован как раздел, добавить в неё записи можно через базу. Либо попробовать через БП, при помощи блока «Изменить права доступа».

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

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

Добрый день, коллеги!

Как можно в bpm'online перевести кроме элементов интерфейса на несколько языков еще и данные?
Необходимо отображать на языке пользователя некоторые поля справочников (Name, Description), а также некоторые поля разделов (например, названия, описания сервисов или продуктов)

Нравится

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

В схеме таблицы для тех полей, которые хотите локализировать, установить признак 'Локализируемый текст' (Localizable Text):

 

По умолчанию для таблиц, которые наследованы от Base lookup, для полей Name и Description эти признаки уже установлены.

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

Для примера на скриншоте ключ выглядит следующим образом: Data:Contact.OfficialName:82d21f9f-4cec-4ff7-aeee-9255cc4f37f3. Contact - это название таблицы, OfficialName - название локализируемого поля, 82d21f9f-4cec-4ff7-aeee-9255cc4f37f3 - Id записи в таблице Contact, для которой делается перевод.

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

В схеме таблицы для тех полей, которые хотите локализировать, установить признак 'Локализируемый текст' (Localizable Text):

 

По умолчанию для таблиц, которые наследованы от Base lookup, для полей Name и Description эти признаки уже установлены.

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

Для примера на скриншоте ключ выглядит следующим образом: Data:Contact.OfficialName:82d21f9f-4cec-4ff7-aeee-9255cc4f37f3. Contact - это название таблицы, OfficialName - название локализируемого поля, 82d21f9f-4cec-4ff7-aeee-9255cc4f37f3 - Id записи в таблице Contact, для которой делается перевод.

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

Спасибо!

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

А как все уже существовавшие записи добавить для перевода?

Посмотреть в профайлере, какие записи добавляются в какие таблицы при добавлении записей в справочник, а потом по всем старым SQL-запросом по аналогии?

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

Добрый день,

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

 

После решил попробовать заполнить справочник вручную нужными значениями

//attributes
"RIBDocType": {
    "dataValueType": Terrasoft.DataValueType.ENUM,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "caption": "RIBDocType"
},
"documentTypeList": {
    "dataValueType": Terrasoft.DataValueType.ENUM,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "isCollection": true
}

//diff
{
	"operation": "insert",
	"parentName": "Header1",
	"propertyName": "items",
	"name": "RIBDocType",
	"values": {
		"bindTo": "RIBDocType",
		"caption": "Тип документа",
		"classes": {"wrapperClass": ["base-edit"]},
		"layout": {"column": 0, "row": 3, "colSpan": 24},
		"textSize": "Default",
		"contentType": Terrasoft.ContentType.ENUM,
		"labelConfig": {
			"visible": true
		},
		"controlConfig": {
			"className": "Terrasoft.ComboBoxEdit",
			"list": {
				"bindTo": "documentTypeList"
			},
			"change": {
				"bindTo": "onMyValueChange"
			},
			"prepareList": {
				"bindTo": "prepareDocumentTypeList"
			}
		}
	},
	"index": 3
}

//methods

onRender: function() {
	if (!this.get("documentTypeList")) {
		this.set("documentTypeList", this.Ext.create("Terrasoft.Collection"));
	}
	
},

prepareDocumentTypeList: function(filter, list) {
	if (list === null) {
		return;
	}
	list.clear();
	var columns = {};
	var value1 = {
		displayValue: "Type1",
		value: "e8670398-603b-43ca-820d-03e5b03fc275"
	};
	var value2 = {
		displayValue: "Type2",
		value: "14fcef3a-7d9e-4737-810f-52d57db3673a"
	};
	var value3 = {
		displayValue: "Type3",
		value: "672606f8-da25-40bd-a4ef-95c958331743"
	};
	columns[1] = value1;
	columns[2] = value2;
	columns[3] = value3;
	list.loadAll(columns);
	console.log(list);
},

onMyValueChange: function(val) {
	if (val && val.displayValue) {
		console.log("you pick: ", val.displayValue);
	}
},

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

 

Нравится

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

Сериков Асхат Кайратович,

Вот, например, код страницы с проекта. Если в attributes добавить lookupListConfig для поля Contact, всё подтянется

/*jshint ignore: start*/
define("UsrSchema", [],
	function() {
		return {
			mixins: {},
			messages: {},
			attributes: {},
			details: {},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"name": "mainBoxContainer",
					"values": {
						"id": "mainBoxContainer",
						"itemType": Terrasoft.ViewItemType.CONTAINER,
						"items": []
					}
				},
				{
					"operation": "insert",
					"name": "mainBoxContainerGrid",
					"parentName": "mainBoxContainer",
					"propertyName": "items",
					"values": {
						"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
						"items": []
					}
				},
				{
					"operation": "insert",
					"parentName": "mainBoxContainerGrid",
					"propertyName": "items",
					"name": "Contact",
					"values": {
						"bindTo": "Contact",
						"caption": "Контакт",
						"contentType": Terrasoft.ContentType.ENUM,
						"layout": {
							"column": 0,
							"row": 0,
							"colSpan": 24
						}
					},
				}
			]/**SCHEMA_DIFF*/,
			methods: {
				init: function() {
					this.callParent(arguments);
				},
 
				getLookupQuery: function(filter, column) {
					var esq = this.callParent(arguments);
					var lookupListConfig = this.getLookupListConfig(column);
					if (lookupListConfig) {
						this.Terrasoft.each(lookupListConfig.columns, function(column) {
							if (!esq.columns.contains(column)) {
								esq.addColumn(column);
							}
						}, this);
					}
 
					var schemaColumn = this.getColumnByName(column);
					if (schemaColumn.lookupListConfig && schemaColumn.lookupListConfig.filter) {
						esq.filters.addItem(schemaColumn.lookupListConfig.filter());
					}
 
					return esq;
				},
				getLookupListConfig: function(columnName) {
					var schemaColumn = this.getColumnByName(columnName);
					if (!schemaColumn) {
						return null;
					}
					var lookupListConfig = schemaColumn.lookupListConfig;
					if (!lookupListConfig) {
						return null;
					}
					var excludedProperty = ["filters", "filter"];
					var config = {};
					this.Terrasoft.each(lookupListConfig, function(property, propertyName) {
						if (excludedProperty.indexOf(propertyName) === -1) {
							config[propertyName] = property;
						}
					});
					return config;
				}
			}
		};
	});
/*jshint ignore: end*/

 

1) Я бы попробовал 

columns[value1.value] = value1;
columns[value2.value] = value2;
columns[value3.value] = value3;

+ в каждом объекте продублировал 

var value1 = {
	displayValue: "Type1",
        name: "Type1",
	value: "e8670398-603b-43ca-820d-03e5b03fc275"
};

чисто на всякий случай

2) Если это своё модальное окно, не унаследованное от basePage, то придётся копировать логику из getLookupQuery (BasePageV2). Там как раз таки и идёт перебор аттрибутов на фильтры, доп колонки и т.п.

Варфоломеев Данила,

Спасибо, да не наследованное, пойду пробовать 

Сериков Асхат Кайратович,

Вот, например, код страницы с проекта. Если в attributes добавить lookupListConfig для поля Contact, всё подтянется

/*jshint ignore: start*/
define("UsrSchema", [],
	function() {
		return {
			mixins: {},
			messages: {},
			attributes: {},
			details: {},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"name": "mainBoxContainer",
					"values": {
						"id": "mainBoxContainer",
						"itemType": Terrasoft.ViewItemType.CONTAINER,
						"items": []
					}
				},
				{
					"operation": "insert",
					"name": "mainBoxContainerGrid",
					"parentName": "mainBoxContainer",
					"propertyName": "items",
					"values": {
						"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
						"items": []
					}
				},
				{
					"operation": "insert",
					"parentName": "mainBoxContainerGrid",
					"propertyName": "items",
					"name": "Contact",
					"values": {
						"bindTo": "Contact",
						"caption": "Контакт",
						"contentType": Terrasoft.ContentType.ENUM,
						"layout": {
							"column": 0,
							"row": 0,
							"colSpan": 24
						}
					},
				}
			]/**SCHEMA_DIFF*/,
			methods: {
				init: function() {
					this.callParent(arguments);
				},
 
				getLookupQuery: function(filter, column) {
					var esq = this.callParent(arguments);
					var lookupListConfig = this.getLookupListConfig(column);
					if (lookupListConfig) {
						this.Terrasoft.each(lookupListConfig.columns, function(column) {
							if (!esq.columns.contains(column)) {
								esq.addColumn(column);
							}
						}, this);
					}
 
					var schemaColumn = this.getColumnByName(column);
					if (schemaColumn.lookupListConfig && schemaColumn.lookupListConfig.filter) {
						esq.filters.addItem(schemaColumn.lookupListConfig.filter());
					}
 
					return esq;
				},
				getLookupListConfig: function(columnName) {
					var schemaColumn = this.getColumnByName(columnName);
					if (!schemaColumn) {
						return null;
					}
					var lookupListConfig = schemaColumn.lookupListConfig;
					if (!lookupListConfig) {
						return null;
					}
					var excludedProperty = ["filters", "filter"];
					var config = {};
					this.Terrasoft.each(lookupListConfig, function(property, propertyName) {
						if (excludedProperty.indexOf(propertyName) === -1) {
							config[propertyName] = property;
						}
					});
					return config;
				}
			}
		};
	});
/*jshint ignore: end*/

 

Варфоломеев Данила,

Спасибо

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

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

Например: Есть справочники Tarifs в нем есть поле Position. И в зависимости от значения Position (1,2,3...)нужно сортировать выпадающий список.

Нравится

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

Это можно сделать при формировании запроса EntitySchemaQuery.

var sortPosition = esq.addColumn("Position");

sortPosition.orderDirection = Terrasoft.OrderDirection.ASC;

Я не уверен, что правильно понял кейс, но у меня, например, есть справочное поле "Рейтинг заявки", где значения от 1 до 10. И десятка идет сразу после единицы, так как оно сортируется как текст. Я на пейдже заявки создал атрибут, где указал сортировку по нужному мне целочисленному полю UsrNumber, которое я чуть ранее добавил в этот справочник.

"UsrRate": {
    lookupListConfig: {
	    orders: [
			{
			    columnPath: "UsrNumber", 
				direction: Terrasoft.OrderDirection.ASC
			}
		]
	}
}

 

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