Все блоги автора

Задача: необходимо реализовать возможность переключения реестра в разделе. То есть, находясь в разделе "Контрагенты" переключать реестры с физическими и юридическими лицами, причём у каждого реестра свои определенные колонки.

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

Решение состоит из 2х частей:

  • Добавить кнопки переключения между представлениями
  • Собственно сделать страницы представленийИзображение удалено.

Добавление кнопок переключения реестров в раздел

Подготовлены спрайты кнопок:

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

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

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

Размер 30*60. Смысл в том, чтобы при наведении мыши фон кнопки съезжал на 30 пикселей, и как бы подсвечивался. Создан модуль, назвать, например SmrCustomButtonsCSS и определить LESS:

.blue-button-wrapper {
     width: 30px;
     height: 30px;
     padding: 0px;
     margin: 0px 5px 0px 5px;
}
.blue-button-image {
     display: inline;
     background-position: 0px 0px;
     width: 30px;
     height: 30px;
     padding: 0px;
     margin: 0px;
}
.blue-button-image:hover {
     display: inline;
     background-position: 0px -30px;
}
.blue-button-pressed {
     display: inline;
     background-position: 0px -30px;
     width: 30px;
     height: 30px;
     padding: 0px;
     margin: 0px;
}

Создана замещающая страница "AccountSectionV2":

 

define("AccountSectionV2", ["ConfigurationConstants", "css!SmrCustomButtonsCSS"],
    function(ConfigurationConstants) {
        return {
            entitySchemaName: "Account",
            attributes: {  },
            methods: {
                showLegalView: function(){
                    this.sandbox. publish( "PushHistoryState", { hash : "SectionModuleV2/LegalAccountSectionV2" });
                },
                showIndividualView: function(){
                    this.sandbox. publish( "PushHistoryState", { hash : "SectionModuleV2/IndividualAccountSectionV2" });
                },
                showAllView: function(){
                    this.sandbox. publish( "PushHistoryState", { hash : "SectionModuleV2/AccountSectionV2" });
                },
                isSwitchButtonsContainerVisible: function() {
                    var isCardVisible = this.get("IsCardVisible");
                    return !isCardVisible;
                }
 
 
            },
            diff: /**SCHEMA_DIFF*/[
 
                {
                    "operation": "insert",
                    "name": "SwitchViewButtonsContainer",
                    "parentName": "ActionButtonsContainer",
                    "propertyName": "items",
                    "values": {
                        "itemType": Terrasoft.ViewItemType.CONTAINER,
                        "visible": {
                            "bindTo": "isSwitchButtonsContainerVisible"
                        },
                        "items": []
                    }
                },
                {
                    "operation": "insert",
                    "parentName": "SwitchViewButtonsContainer",
                    "propertyName": "items",
                    "name": "SwitchToAllDataView",
                    "values": {
                        "layout": {
                            "column": 23,
                            "row": 0,
                            "colSpan": 1,
                            "rowSpan": 1
                        },
                        "itemType": Terrasoft.ViewItemType.BUTTON,
                        "style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                        //"iconAlign": Terrasoft.controls.ButtonEnums.iconAlign.RIGHT,
                        iconAlign: Terrasoft.controls.ButtonEnums.iconAlign.TOP,
                        pressed: {bindTo: "LegalGridActive"},
                        "imageConfig": {
                            "source": Terrasoft.ImageSources.SOURCE_CODE_SCHEMA,
                            "params": {
                                "schemaName": "SmrCustomButtonsCSS",
                                "resourceItemName": "GridDataViewIconBlue"
                            }
                        },
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-pressed"
                        },
                        "click": {"bindTo": "showAllView"}
                    }
                },
                {
                    "operation": "insert",
                    "parentName": "SwitchViewButtonsContainer",
                    "propertyName": "items",
                    "name": "SwitchToPersonalDataView",
                    "values": {
                        "layout": {
                            "column": 23,
                            "row": 0,
                            "colSpan": 1,
                            "rowSpan": 1
                        },
                        "itemType": Terrasoft.ViewItemType.BUTTON,
                        "style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                        //"iconAlign": Terrasoft.controls.ButtonEnums.iconAlign.RIGHT,
                        iconAlign: Terrasoft.controls.ButtonEnums.iconAlign.TOP,
                        pressed: {bindTo: "LegalGridActive"},
                        "imageConfig": {
                            "source": Terrasoft.ImageSources.SOURCE_CODE_SCHEMA,
                            "params": {
                                "schemaName": "SmrCustomButtonsCSS",
                                "resourceItemName": "GridPersonalDataViewIconBlue"
                            }
                        },
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image"
                        },
                        "click": {"bindTo": "showIndividualView"}
                    }
                },
                {
                    "operation": "insert",
                    "parentName": "SwitchViewButtonsContainer",
                    "propertyName": "items",
                    "name": "SwitchToLegalDataView",
                    "values": {
                        "layout": {
                            "column": 23,
                            "row": 0,
                            "colSpan": 1,
                            "rowSpan": 1
                        },
                        "itemType": Terrasoft.ViewItemType.BUTTON,
                        "style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                        //"iconAlign": Terrasoft.controls.ButtonEnums.iconAlign.RIGHT,
                        iconAlign: Terrasoft.controls.ButtonEnums.iconAlign.TOP,
                        pressed: {bindTo: "LegalGridActive"},
                        "imageConfig": {
                            "source": Terrasoft.ImageSources.SOURCE_CODE_SCHEMA,
                            "params": {
                                "schemaName": "SmrCustomButtonsCSS",
                                "resourceItemName": "GridLegalDataViewIconBlue"
                            }
                        },
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image",
                            pressedClass: "blue-button-pressed"
                        },
                        "click": {"bindTo": "showLegalView"}
                    }
                }
 
            ]/**SCHEMA_DIFF*/
        };
    }
);

Страницы разделов

Созданы 2 страницы разделов. Код для реестра физических лиц:

define("IndividualAccountSectionV2", ["ConfigurationConstants", "css!SmrCustomButtonsCSS"],
    function(ConfigurationConstants) {
        return {
            entitySchemaName: "Account",
            methods: {
                /**
                 * Инициализирует  фильтры экземпляра запроса
                 * @protected
                 * @overridden
                 * @param {Terrasoft.EntitySchemaQuery} esq Запрос, в котором будут инициированы фильтры
                 */
                initQueryFilters: function (esq) {
                    this.callParent(arguments);
                    esq.filters.removeByKey("ClientType");
                    esq.filters.add("ClientType", this.Terrasoft.createColumnFilterWithParameter(
                        this.Terrasoft.ComparisonType.EQUAL, "SmrClientType.Id", "80FD3F74-0AF4-4F8A-9F0B-F626E4F05147"));
                },
                /**
                 * Возвращает представления раздела по умолчанию.
                 * Реестр, Аналитика не создаётся
                 * @overridden
                 * @return {Object} Представления раздела по умолчанию
                 */
                getDefaultDataViews: function() {
                    var gridDataView = {
                        name: this.get("GridDataViewName"),
                        caption: this.getDefaultGridDataViewCaption(),
                        icon: this.getDefaultGridDataViewIcon()
                    };
                    var analyticsDataView = {
 
                    };
                    return {
                        "GridDataView": gridDataView,
                        "AnalyticsDataView": analyticsDataView
                    };
                },
                /**
                 * Получает пункты меню кнопки "Вид"
                 * @overridden
                 * @virtual
                 * @return {Terrasoft.BaseViewModelCollection} Возвращает пункты меню кнопки "Вид"
                 */
                getViewOptions: function() {
                    var viewOptions = this.Ext.create("Terrasoft.BaseViewModelCollection");
                    viewOptions.addItem(this.getButtonMenuItem({
                        "Caption": {"bindTo": "Resources.Strings.SortMenuCaption"},
                        "Items": this.get("SortColumns")
                    }));
                    viewOptions.addItem(this.getButtonMenuItem({
                        "Caption": {"bindTo": "Resources.Strings.OpenGridSettingsCaption"},
                        "Click": {"bindTo": "openGridSettings"}
                    }));
                    return viewOptions;
                }
            },
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "SwitchToAllDataView",
                    "values": {
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image"
                        }
                    }
                },
                {
                    "operation": "merge",
                    "name": "SwitchToPersonalDataView",
                    "values": {
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-pressed"
                        }
                    }
                },
                {
                    "operation": "merge",
                    "name": "SwitchToLegalDataView",
                    "values": {
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image"
                        }
                    }
                }
            ]/**SCHEMA_DIFF*/
        };
    }
);

Код страницы для реестра юридических лиц:

define("LegalAccountSectionV2", ["RightUtilities", "ConfigurationConstants", "css!SmrCustomButtonsCSS"],
    function (RightUtilities, ConfigurationConstants) {
        return {
            entitySchemaName: "Account",
            attributes: {},
            messages: {},
            methods: {
                /**
                 * Инициализирует  фильтры экземпляра запроса
                 * @protected
                 * @overridden
                 * @param {Terrasoft.EntitySchemaQuery} esq Запрос, в котором будут инициированы фильтры
                 */
                initQueryFilters: function (esq) {
                    this.callParent(arguments);
                    esq.filters.removeByKey("ClientType");
                    esq.filters.add("ClientType", this.Terrasoft.createColumnFilterWithParameter(
                        this.Terrasoft.ComparisonType.EQUAL, "SmrClientType.Id", "DD4E6E34-21D3-4F09-A417-6FC4116876B5"));
                },
                /**
                 * Возвращает представления раздела по умолчанию.
                 * Реестр, Аналитика не создаётся
                 * @overridden
                 * @return {Object} Представления раздела по умолчанию
                 */
                getDefaultDataViews: function() {
                    var gridDataView = {
                        name: this.get("GridDataViewName"),
                        caption: this.getDefaultGridDataViewCaption(),
                        icon: this.getDefaultGridDataViewIcon()
                    };
                    var analyticsDataView = {
 
                    };
                    return {
                        "GridDataView": gridDataView,
                        "AnalyticsDataView": analyticsDataView
                    };
                },
                /**
                 * Получает пункты меню кнопки "Вид"
                 * @overridden
                 * @virtual
                 * @return {Terrasoft.BaseViewModelCollection} Возвращает пункты меню кнопки "Вид"
                 */
                getViewOptions: function() {
                    var viewOptions = this.Ext.create("Terrasoft.BaseViewModelCollection");
                    viewOptions.addItem(this.getButtonMenuItem({
                        "Caption": {"bindTo": "Resources.Strings.SortMenuCaption"},
                        "Items": this.get("SortColumns")
                    }));
                    viewOptions.addItem(this.getButtonMenuItem({
                        "Caption": {"bindTo": "Resources.Strings.OpenGridSettingsCaption"},
                        "Click": {"bindTo": "openGridSettings"}
                    }));
                    return viewOptions;
                }
            },
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "SwitchToAllDataView",
                    "values": {
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image"
 
                        }
                    }
                },
                {
                    "operation": "merge",
                    "name": "SwitchToPersonalDataView",
                    "values": {
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image"
                        }
                    }
                },
                {
                    "operation": "merge",
                    "name": "SwitchToLegalDataView",
                    "values": {
                        classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-pressed"
                        }
                    }
                }
            ]/**SCHEMA_DIFF*/
        };
    });

Что нужно отметить в этих страницах:

/**
 * Инициализирует  фильтры экземпляра запроса
 * @protected
 * @overridden
 * @param {Terrasoft.EntitySchemaQuery} esq Запрос, в котором будут инициированы фильтры
 */
initQueryFilters: function (esq) {
        this.callParent(arguments);
        esq.filters.removeByKey("ClientType");
        esq.filters.add("ClientType", this.Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.EQUAL, "SmrClientType.Id", "DD4E6E34-21D3-4F09-A417-6FC4116876B5"));
}

Мы переопределяем метод для установки фильтрации записей (например, только физические лица).

Также, переопределяем методы getDefaultDataViews и getViewOptions, чтобы скрыть функции, которые не работают в новых реестрах (почему - не было времени разбираться).

 

Проблемы

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

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

Нравится

Поделиться

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

Эх, еще бы это в Мастер раздела :)

Кстати, а кейс ведения физических и юридических лиц в Контрагентах давно стал практикой?

Это практика при условиях, что:

  • Клиенту нужно смотреть суммарную разнообразную аналитику по всем клиентам физики+юрики, создаваемую через стандартные средства (в представлении "Аналитика")
  • Клиента бесит, когда ему каждый раз заходя в раздел Контакты, нужно отфильтровывать своих сотрудников и сотрудников подрядчиков, чтобы поработать с клиентами:smile:

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

Рад помочь, для этого и нужно комьюнити:smile:. Если есть еще вопросы в стиле "В 3ке это делалось в 5 кликов аналитиком, а как это сделать это в 7ке?" - спрашивайте, наверняка найдем проектное решения в закромах, пусть и не всегда очевидное:lol:

"Александр Свистунов" написал:спрашивайте, наверняка найдем проектное решения в закромах

Я ж воспользуюсь :)
Case: отфильтровать в разделе Счета все счета, к которым прикреплен продукт = "ххх". То есть фильтр по вхождению некой информации в деталь - аналогично в любом разделе. Так как штатно доступны только фильтры по детали с агрегатной функцией, то видимо надо как-то добавлять свой фильтр?
В 3х это делалось через модификацию sq_, в 5х вроде как вообще работало штатно через обратные связи.
Раздел итоги элемент список не предлагать :) там делается посредством списка на основании Продукт в счете - пробовал, работает.

Александр, если я правильно понял ваш Кейс, то это делается через подобный фильтр

Продукт в счете

"Толмачев Дмитрий Юрьевич" написал:делается через подобный фильтр

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

Чтобы темы не плодить... товарищи, как бы попроще скрыть из меню Edit, Copy и особенно Delete для детали, основанной на вьюшке?
Деталь самодельная, родитель BaseGridDetailV2.

Александр,

Для решения вашей задачи достаточно переопределить функцию addRecordOperationsMenuItems на созданной вами странице реестра

methods: {
	/**
	 * @overridden
	 */
	addRecordOperationsMenuItems: Ext.emptyFn
	//...
}

"Толмачев Дмитрий Юрьевич" написал:Ext.emptyFn

Спасибо, попробую так.
Я ее нашел, только наивно переопределял как

addRecordOperationsMenuItems: function() {
}

То есть пытался заполнить "ничем"...

А я где-то такую функцию нашёл

getAddRecordButtonVisible: function() {
	return false;
},

Добрый день!

Александр, спасибо за предоставленной пример, остался один непонятный для меня момент, какие действия нужно выполнить, что бы новая страница раздела (например, IndividualAccountSectionV2) стала доступна по URL "http://localhost/0/Nui/ViewModule.aspx#SectionModuleV2/IndividualAccoun…"?

Сергей,

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

В данном случае, насколько я помню, у страниц LegalAccountSectionV2 и IndividualAccountSectionV2 в качестве родительской использовалась "AccountSectionV2", т.к. по сути это дочерние ветки.

Александр, большое спасибо за то что делитесь отличным материалом!

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

1. Правильно ли я понимаю, что через свойства Diff:

pressed: {bindTo: "LegalGridActive"},

и

classes: {
                            wrapperClass: "blue-button-wrapper",
                            imageClass: "blue-button-image",
                            pressedClass: "blue-button-pressed"
                        },

Вы указываете, будет ли элемент содержать класс "blue-button-pressed" ?
Если да, то что в этом случае должна возвращать функция "LegalGridActive" - true или false?

У меня на версии 7.7 не получилось сделать так, чтобы к елементу "прицепился" мой класс указанный в pressedClass (как у Вашем примере: pressedClass: "blue-button-pressed"). Вместо него появился "дефолтный" класс - t-btn-pressed.
вот код DIFF:

	{
		"operation": "insert",
		"parentName": "SignButtonsContainer",
		"propertyName": "items",
		"name": "SignBtnVip",
		"values": {
			"itemType": Terrasoft.ViewItemType.BUTTON,
			"caption": {"bindTo": "sign_Vip"},
			"hint": {"bindTo": "Resources.Strings.sign_Vip"},
			"imageConfig" : {"bindTo": "Resources.Images.sign_vip_Image"},
			//"click": {"bindTo": "onVipButtonClick"},
			pressed : {bindTo : "VipButtonPressed"},
			classes : {
				wrapperClass : "sign-btn",
				imageClass   : "sign-img",
				pressedClass : "sign-img-pressed"
			},
			"visible": true
		}
	},

В итоге вместо ожидаемого css-класса "sign-img-pressed" - появляется "t-btn-pressed". Не могу понять что я сделал не так...

2. Можно ли какимто образом отключить для моего елемента генерацию стандрартных css-классов?
(для элемента Terrasoft.ViewItemType.BUTTON сгенерировались - t-btn-wrapper, t-btn-no-text-padding, t-btn-style-default )

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

В целом, очень хорошо что в 7-ке есть возможность подключать свои css-стили, это очень удобно, но вот генерация самих классов для элемента происходит немного не очевидно... :smile:

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

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

Как можно реализовать данный функционал?

Нравится

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

Добрый день!

Ниже приведу алгоритм примера реализации, как сделать, чтобы была подсветка записей реестра если у продажи на объекте поле IsNotInterest = true:

1. Создаем метод gridRecolor

gridRecolor: function () {
   var gridData = this.getGridData();
   var items = gridData.getItems();
   var loadedObject = {};
   Terrasoft.each(items, function (item) {
      item.customStyle = null;
      var facilityId = item.get("Facility").value;
      var opportunityId = item.get("Opportunity").value;
      var isNotInterest = item.get("IsNotInterest");
      //Если условие подходит, меняем цвет записи на темно-серый.
      if (isNotInterest) {
         item.customStyle = {
           'color' : "darkgrey"
         }
      }
      var primaryValue = item.get(item.primaryColumnName);
      //Формируем новый набор данных уже с подсветкой
      loadedObject[primaryValue] = item;
   }, this);
   gridData.clear();
   //загружаем новый набор данных
   gridData.loadAll(loadedObject);
},

2. Замещаем метод onGridDataLoaded, добавив в него вызов gridRecolor

onGridDataLoaded: function () {
   this.callParent(arguments);
   this.gridRecolor();
},

3. Profit!

Дмитрий, ваш пример работает, но мне нужно изменить цвет не у всей записи, а конкретно проверяемой колонки.

"Пащенко Александр Сергеевич" написал:

Дмитрий, ваш пример работает, но мне нужно изменить цвет не у всей записи, а конкретно проверяемой колонки.

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

Добрый день!

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

 

Добрый день!

Такая реализация выделяет цветом текстовое содержимое записи. А можно сделать так, чтобы выделялась цветом весь ряд/запись как фон указанного цвета?

Есть бесплатное дополнение Records color highlighting.

Вильшанский Дмитрий,

можно покрасить просто строку указав 

item.customStyle =  {

                    'color' : "black",

                    'background' : "#33FF33"

                         }

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

Добрый день.
Terrasoft XRM 3.3.2.304. Столкнулся с такой ситуацией.
В гриде детали необходимо программно скрывать и вытаскивать колонки.
делаю так:

Window.ComponentsByName('colYearNumber').IsVisible = true;     

если колонка была скрыта, то получаю вот такой результат:

нажимаем F5:

Аналогичный эффект достигается при попытке программного назначения ActiveView.
В чем может быть причина и как это победить?
Спасибо

Нравится

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

В SelectQuery поставьте для поля "Всегда выбирать в запросе"

Дмитрий, спасибо огромное.

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

Подскажите можно ли раскрасить в разные цвета строки реестра в bpm 5.4 on-site?

Нравится

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

Доброе утро, Илья. Ознакомьтесь с примером.

На PageLoad подписываемся на событие:

Page.DataSource.Loaded += Page.TreeGrid.DataLoaded;
Page.TreeGrid.GetRowConfigHandler += GetRowConfig;

Пример метода, который реализует подсветку в зависимости от Статуса контрагента:

public virtual DataSourceRowConfig GetRowConfig(Entity row) {
    string primaryColumnName = row.Schema.PrimaryColumn.Name;
    string primaryColumnValue = row.GetColumnValue(primaryColumnName).ToString();
    Dictionary<Guid,string> Colors = new Dictionary<Guid,string>();
    Colors = (Dictionary<Guid,string>)objColors;
    var config = new DataSourceRowConfig(primaryColumnValue);
    string backgroundColor = string.Empty;
    var statusId = row.GetTypedColumnValue<Guid>("AccountStatusId");
    if(statusId != Guid.Empty && Colors.Count > 0){
        backgroundColor = Colors[statusId];
    }
    if(!string.IsNullOrEmpty(backgroundColor)){
        config.AddConfig(new DataSourceRowBackgroundColorConfigValue(backgroundColor));
    }
    string[] dropTags = new string[] {Page.DataSource.Schema.Name};
    config.AddConfig(new DataSourceRowDragTagsConfigValue(dropTags));
    return config;                          
}

backgroundColor можно присваивать значения в таком виде:

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

День добрый! Не знаю, знаете ли вы, но я теперь знаю, что в BPMonline 5.X можно редактировать записи в реестре, не открывая карточек редактирования. Выглядит это, как будто работа в ячейках Excel - Youtube.
Далее расскажу, как это настроить.

Во-первых

нужно разрешить редактирование в ячейках реестра
Заходим в страницу реестра контрагентов (для других разделов - соответствующие страницы) и выбираем TreeGrid, отображать все свойства и ставим галочку "Разрешить редактирование в ячейках":

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

Во-вторых

нужно включить подгрузку данных
На той же страницу для всех колонок в DataSource проставляем галочку "Всегда загружать данные":

После этого будем получать ошибку об отсутствии данных в каком-нибудь другом поле:lol: У меня это было AddressType:

В-третьих

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

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

Нравится

Поделиться

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

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

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

BPM 5.4.0
Может кто сталкивался с такой проблемой. Есть две детали, но смотреть их по отдельности, переключаясь от одной к другой, неудобно.
Необходимо их объединить. Так чтобы в одном окне были два этих реестра (один под другим или слева и справа неважно). Как сделать, есть ли примеры?

Нравится

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

Здравствуйте, Александр!
Такая деталь реализована в BPMonline Service Desk (раздел "Инциденты" (или "Обращения"), деталь "Комментарии").
Принцип следующий:
на страницу детали добавляется два layout'а. В один помещается собственно реестр детали, а в другой - страница реестра дополнительной детали:

Обратите внимание на положение компонента DataSource. В текущей реализации это важно!

Нет возможности развернуть Service Desc (у клиента CRM) может там есть примеры, если нет, то не могли бы скинуть файлик окна?

Прикрепил архив с самим окном и связанными схемами (объект "Комментарий" и страница реестра файлов в комментарии), без которых, скорее всего, импортировать окно не получится.

commentary.rar

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

В процессе эксплуатации BPM я понял, что если у меня есть реестр в детали или основной реестр в разделе, то перейти к "связанным" записям (например Договор - поле "Контрагент", "Контакт", и так далее) можно через контекстное меню "Перейти к..." только если в реестре отображается колонка с соответствующим полем.
А если полей-справочников много, все колонки мне видеть совершенно ни к чему, но переход к этим записям все же нужен? Понятно, что можно сделать свое контекстное меню с нужными пунктами:smile:
Но наверняка есть некий простой способ добиться отображения всех "связанных" объектов в штатном меню независимо от настроек реестра?

И сразу же второй вопрос - а от какого параметра/хитрого скрипта зависит то, что из детали раздела можно перейти к соответствующей записи в разделе? Скажем из детали "Продукты" в "Документах" перейти в раздел "Продукты"? Нет ведь такой возможности по-умолчанию.

Нравится

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

Здравствуйте, Александр!
Формирования списка меню "Перейти к" формируется в mainPage в обработчике события "PageLoadComplete", а если конкретнее, то начиная с 159 строки:

var entitySchemaQuery = new EntitySchemaQuery(entitySchemaManager, "SysModule");
entitySchemaQuery.Cache = UserConnection.SessionCache.WithLocalCaching(TSConfiguration.CacheUtilities.WorkspaceCacheGroup);
EntitySchemaQueryColumn entitySchemaColumn = entitySchemaQuery.AddColumn("SysModuleEntity.SysEntitySchema");			
EntitySchemaQueryColumn pageSchemaColumn = entitySchemaQuery.AddColumn("SysPageSchema");
entitySchemaQuery.Filters.Add(entitySchemaQuery.CreateIsNotNullFilter("[SysModuleInSysModuleFolder:SysModule].Id"));
entitySchemaQuery.CacheItemName = "window.modules";
EntityCollection modulesCollection = entitySchemaQuery.GetEntityCollection(Page.UserConnection);
var modules = new Dictionary<string, Guid>();
foreach(var module in modulesCollection) {
	var pageSchemaId = entitySchemaQuery.GetTypedColumnValue<Guid>(module, pageSchemaColumn.Name);
	var schemaId = entitySchemaQuery.GetTypedColumnValue<Guid>(module, entitySchemaColumn.Name);
	string key = "'"+schemaId.ToString()+"'";
	if ((pageSchemaId != Guid.Empty) && (schemaId != Guid.Empty) && (!modules.ContainsKey(key))) {
		modules.Add(key, pageSchemaId);
	}
}

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

Андрей, посмотрел данный код... результатом его является просто список некоторых реквизитов ВСЕХ модулей системы. Не вижу формирования элемента контекстного меню. Нет назначения элементу меню обработчика.
Формирование меню где-то глубже...

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

"Андрей Каспаревич" написал:
После консультации в отделе разработки сказали, что заполнение этого меню происходит в ядре и конфигурационно не получится добавить или удалить из него пункты.

Андрей, а можно ли уточнить принципы формирования - они совершенно не понятны. Примеры я привел - деталь Продукты в Документах, нет перехода к продукту (1). В реестре есть переход только к тем объектам, соответствующие которым колонки вынесены в реестр (2). Но, несмотря на (2), в детали продукты поле Продукт (справочник!) в реестр вынесено и перехода по-прежнему нет...
Можно сформулировать это как пожелание - чтобы в реестрах был всегда переход ко всем связанным объектам (как это всегда работало в продуктах линейки 3.х)
Переход из дочерней детали (пример 1) в раздел, допускаю что сделать сложнее, но опять же выскажу это пожелание...

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

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

Создал новый сервис с помощью мастера, Затем дополнил его новыми полями. Создал карточку редактирования. Работает, при заполнении в базе появляется запись в соответствующей таблице (проверял).
Однако, необходимо чтобы записи отображались в реестре и главном разделе нового раздела. Обе формы созданы, но этого не происходит.
Проверял по инструкции https://community.terrasoft.ru/developer/advice/4567 : соответствующие обработчики событий сгененрированы мастером, соответствующие поля заполнены, компоненты созданы.
В чём может быть ошибка?

Нравится

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

А есть корневая группа в дереве групп? Если есть, то есть ли на неё права у текущего пользователя?

Простите, но я не совсем понимаю, что подразумевается под коневой группой, Main Grid нет?

Например, группа "Все контакты".

Добрый день, Игорь, действительно, проблема скорее всего с правами доступа. Ранее с похожими проблемами уже поступали обращения.

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

А есть корневая группа в дереве групп? Если есть, то есть ли на неё права у текущего пользователя?


Да, есть, полные права

Господа-эксперты, проблема не решена...
Есть-ли у кого-нибудь ещё мысли по этому поводу?

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

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

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

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

Сообщение переслал, первое не дошло.
Решением проблемы явилось удаление раздела и создание нового.
Видимо где-то накосячил

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

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

var Column = Self.CreateComponent('DataGridColumn', 'colProcessed');
grdData.ActiveView.Add(Column);
grdData.ActiveView.ItemsByName('colProcessed').DataFieldName = 'Processed';

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

var ColumnObject = grdData.ActiveView.ItemsByName('colProcessed');
grdData.ActiveView.RemoveItem(ColumnObject);

Нравится

Поделиться

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

От пользователя поступило следующее обращение:

Цитата:
Можно ли сделать так, чтобы в объекте «Документы» все документы которые просрочены подсвечивались иным цветом, или выделялись жирным шрифтом?

Для реализации данной задачи необходимо внесение доработок в конфигурацию.

Рассмотрим доработку на примере коробочной конфигурации:

Просроченными считаются те документы, у которых дата меньше, чем неделю назад и состояние отличается от Утвержден.

Откройте Terrasoft Administrator (Пуск - Программы - Terrasoft) и найдите сервис wnd_DocumentsGridArea:

111

Выберите компонент grdData, и установите его свойство HasCustomDraw равным true:

111

Затем перейдите в События для данного компонента, и создайте обработчик события OnGetRowDrawInfo двойным кликом в поле напротив нужного события:

111

После создания события Вы автоматически перейдете в скрипт (для версий 3.3.2 и новее). добавьте в скрипт программный код обработки события:

        var GridDataset = DataGrid.DatasetLink.Dataset;
        var IsOverdue = GetDateDiff(DataGrid.DatasetLink.Dataset('Date'), new Date(), 'Day') > 0;
        var dsClosed = '{670FDB86-A5EB-4AC0-9CCF-E303C5A8016E}'; //состояние Утвержден
        if((GridDataset('StateID') != dsClosed)&& IsOverdue){
                Color.Value = clPink;
                Font.Bold = true;
        }

111

Сохраните скрипт. Сохраните карточку. Перезапустите Terrasoft.

Совет: Полный список констант цвета есть в скрипте scr_Consts. Вы можете также задать собственный цвет в формате 0xE6CCB7

Нравится

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