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

EntityConnections: {
                                schemaName: "EntityConnectionsDetailV2",
                                entitySchemaName: "EntityConnection",
                                filter: {
                                        masterColumn: "Id",
                                        detailColumn: "SysModuleEntity"
                                }
                        },

{
                                "operation": "insert",
                                "parentName": "GeneralInfoTab",
                                "propertyName": "items",
                                "name": "EntityConnections",
                                "values": {
                                        itemType: Terrasoft.ViewItemType.DETAIL
                                }
                        },

но просто так не работает. Подскажите пожалуйста что еще нужно добавить.

Нравится

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

Здравствуйте!

Например, необходимо добавить записи в таблицу EntityConnection.
В эту таблицу нужно добавить следующее:
1) ColumnUId - UId поля с метаданных объекта раздела, в который добавляется деталь связи
2) SysEntitySchemaUId - UId объекта раздела из таблицы SysSchema.

Здравствуйте!

Например, необходимо добавить записи в таблицу EntityConnection.
В эту таблицу нужно добавить следующее:
1) ColumnUId - UId поля с метаданных объекта раздела, в который добавляется деталь связи
2) SysEntitySchemaUId - UId объекта раздела из таблицы SysSchema.

Открыл допустим обьект Document рис. 1.
Сделал в базе запрос:

select * from EntityConnection where ColumnUId = '8b33b6b2-19f7-4222-9161-b4054b3fbb09'

Ничего нет, какой именно Id нужно брать?

Уже не нужно разобрался. Спасибо.

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

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

Известный модуль MultiMaskEdit позволяет реализовать маску, но значение в базу данных записывает в таком же виде. Если при сохранении очистить значение от ненужных символов, то при последующей загрузке значение не отображается, т.к. не соответствует маске. Также не отображаются частичные значения.
Например при маске +7(999) 999-99-99 и значении +7(999) 123-34-5 мы не увидим значения.

Нравится

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

Смотрел, с этих тем и начал. Проблема подробно описана в первом посте. Маска нужна только для отображения, но не для записи в базу.

Хардкод-решение. Сделать два поля, одно — номер с символами, другое — только цифры. Маску привязать к первому полю. Второе заполнять программно при изменении первого (при помощи БП или триггера в БД).

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

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

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

Нравится

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

Облако/онсайт?
Как минимум очистить кэш браузера, сбросить сессии redis
Картинка в корп. сети не видна была у меня, извините...
Попробуйте еще раз Компилировать все

Буквально недавно столкнулся с такой же проблемой. Саппорт порекомендовал зайти <адрес сайта>/0/dev и "компилировать все". Мне лично помогло

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

Текст ошибки такой: Сборка конфигурации Default не инициализирована

"Варфоломеев Данила" написал:<адрес сайта>/0/dev

не знал про dev кстати
раньше сюда посылали, одно и то же открывается <адрес сайта>/0/workspaceexplorermodule.aspx

"Калёнов Дмитрий Алексеевич" написал:никуда не пускает

<адрес сайта>/0/dev сюда тоже не пускает?

Здравствуйте!

в корневом web.config установите в false:

    <fileDesignMode enabled="false" UseIDEForCompilation="false" />
Показать все комментарии

Здравствуйте! Мне нужно, чтобы в Расписании выделялись цветом те задачи, которые имеют в заголовке слово "Свободно".

Если реализовать через такой код

define("ActivitySectionV2", [],
    function () {
        return {
            // Название схемы раздела.
            entitySchemaName: "Activity",
                details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
                diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
            methods: {
                // Переопределение базового метода, который модифицирует строку данных перед загрузкой в реестр.
                prepareResponseCollectionItem: function (item) {
                    this.callParent(arguments);
                    item.customStyle = null;
                    var running = item.get("Title");
                    //Если условие подходит, меняем цвет записи на темно-серый, а фон на светло-зеленый.
                    if (running.indexOf('Свободно')+1) {
                        item.customStyle = {
                            'color': "darkgrey",
                            'background': "#D8FBC2"
                        }
                    }
                }
            }
        };
    });


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

 

Как сделать так чтобы в расписании активность поменяла свой цвет если в заголовке есть слово "Свободно"?
Версия BpmOnline sales commerce 7.8.3.1978

Нравится

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

Извините за оффтопик.
Не делали бы вы для раскраски реестров парсинг текста заголовка, ляжет и погибнет у вас система как объемы данных нарастут... это же неиндексируемое поле, да еще поиск по тексту...
Тут бы признак сделать типа булевского поля, и по нему обрабатывать. А булевское поле заполнять например тем самым парсингом названия при сохранении активности.

по теме
посмотрите в ActivitySectionV2 поиском по тексту "FontColor" -найдете в diff описание конфига для отображения элементов расписания. Возможно поможет замещение и замена bindto для fontcolor на новый атрибут... но это предположение :)

Раскраска активностей в расписании

Описание таска

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

Анализ

Таблица расписания определена внутри пакета NUI в модуле ActivitySectionV2, как элемент в объекте diff с именем Schedule. В данный элемент вложен объект itemBindingConfig, который отвечает за привязку свойств активности к каждому из элементов расписания. В данном случае нас интересуют два значения, а именно: background, устанавливающий цвет фона элемента расписания и fontColor, определяющий цвет текста на нём.
Привязанные методы (то, что идёт после bindTo, например, getScheduleItemTitle) определяются внутри пакета UIv2 в модуле ActivitySectionGridRowViewModel. Привязанные поля есть ничто иное, как загруженные из базы данных поля схемы Activity, список которых определяется внутри модуля ActivitySectionV2 в методе getGridDataColumns. Обратите внимание, что по умолчанию background и fontColor привязаны к полям, которых нет в схеме Activity (Background и FontColor соотвественно).
Внутренняя логика поведения элемента расписания определена в файле schedule-item.js (класс Terrasoft.controls.ScheduleItem). После анализа этого кода становится ясно, что в случае, если background определён, то CSS стиль элемента меняется, в противном случае – нет. То же касается и fontColor:

if (background && isSelected) {
   out.push('<div style="background: ' + background + ';" class="' + schedulerItemStatusClasses[status] +
      " " + schedulerItemStatusClasses[0] + '">');
} else if (background && !isSelected) {
   out.push('<div style="background: ' + background + ';" class="' + schedulerItemStatusClasses[status] +
      '">');
} else if (!background && isSelected) {
   out.push('<div class="' + schedulerItemStatusClasses[status] + " " + schedulerItemStatusClasses[0] +
      '">');
} else {
   out.push('<div class="' + schedulerItemStatusClasses[status] + '">');
}

Также можно заметить ещё одну особенность. Свойства background и fontColor не применяется для элементов, выделенных пользователем нажатием мыши:

…
itemBodyEl.setStyle({
   "backgroundColor": (isSelected) ? "" : this.background,
   "color": (isSelected) ? "" : this.fontColor
});

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

Реализация

Шаг 1. Добавление справочника.
Первым шагом будет добавление справочника ActivitySchedulerColor. Дадим ему заголовок «Цвет активности в расписании» и добавим следующие поля:

  • ActivityPriority с типом Справочник, который ссылается на «Приоритет активности».
  • BackgroundColor с типом Строка
  • FontColor с типом Строка

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

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

define("ActivitySectionGridRowHelper", ["terrasoft"], function(Terrasoft) {
    var activitySchedulerColor = {};
 
    //Возвращает соответствующие priorityId цвета из справочника ActivitySchedulerColor
    //Перед вызовом этого метода, необходимо загрузить данные из справочника методом loadActivitySchedulerColors
    function getActivitySchedulerColor(priorityId) {
        return activitySchedulerColor[priorityId];
    }
 
    //Загружает данные из справочника ActivitySchedulerColor (Цвета активностей)
    function loadActivitySchedulerColors() {
        var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "ActivitySchedulerColor"});
        esq.addColumn("ActivityPriority", "ActivityPriority");
        esq.addColumn("BackgroundColor", "BackgroundColor");
        esq.addColumn("FontColor", "FontColor");
        esq.getEntityCollection(function(response) {
            Terrasoft.each(response.collection.collection.items, function(item) {
                activitySchedulerColor[item.values.ActivityPriority.value] = {
                    "backgroundColor":item.values.BackgroundColor,
                    "fontColor":item.values.FontColor
                };
            }, this);
        });
    }
 
    return {
        GetActivitySchedulerColor: getActivitySchedulerColor,
        LoadActivitySchedulerColors: loadActivitySchedulerColors
    };
});

Шаг 3. Замещение модуля ActivitySectionV2.
Следующим шагом будет переопределение схемы ActivitySectionV2. Здесь нужно изменить привязку значений для таблицы расписания, добавить поле Priority в выборку данных для таблицы расписания и вызвать из хелпера метод loadActivitySchedulerColors:

define("ActivitySectionV2", ["ActivitySectionGridRowHelper"],
    function(ActivitySectionGridRowHelper) {
        return {
            entitySchemaName: "Activity",
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "Schedule",
                    "values": {
                        "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": "getBackground"},
                            "fontColor": {"bindTo": "getFontColor"},
                            "isBold": {"bindTo": "IsBold"},
                            "isItalic": {"bindTo": "IsItalic"},
                            "isUnderline": {"bindTo": "IsUnderline"},
                            "markerValue": {"bindTo": "getScheduleItemHint"}
                        }
                    }
                }
            ]/**SCHEMA_DIFF*/,
            methods: {
                getGridDataColumns: function() {
                    var baseGridDataColumns = this.callParent(arguments);
                    var gridDataColumns = {
                        "Account": {path: "Account"},
                        "StartDate": {path: "StartDate"},
                        "DueDate": {path: "DueDate"},
                        "ShowInScheduler": {path: "ShowInScheduler"},
                        "Status": {path: "Status"},
                        "Status.Finish": {path: "Status.Finish"},
                        "ProcessElementId": {
                            path: "ProcessElementId",
                            dataValueType: 0
                        },
                        "Priority": {path: "Priority"}
                    };
                    return Ext.apply(baseGridDataColumns, gridDataColumns);
                },
                init: function () {
                    this.callParent(arguments);
                    ActivitySectionGridRowHelper.LoadActivitySchedulerColors();
                }
            }
        };
    });


Шаг 4. Замещение модуля ActivitySectionGridRowViewModel.

В данный модуль нам необходимо добавить два метода getBackground и getFontColor, к которым мы привязали значения полей background и fontColor. Однако, так как все методы объявлены внутри Ext.define, придётся копировать весь код модуля:

define("ActivitySectionGridRowViewModel", ["ext-base", "terrasoft", "ActivitySectionGridRowHelper","BaseSectionGridRowViewModel"],
    function(Ext, Terrasoft, ActivitySectionGridRowHelper) {
 
        /**
         * @class Terrasoft.configuration.ActivitySectionGridRowViewModel
         */
        Ext.define("Terrasoft.configuration.ActivitySectionGridRowViewModel", {
            extend: "Terrasoft.BaseSectionGridRowViewModel",
            alternateClassName: "Terrasoft.ActivitySectionGridRowViewModel",
 
            /**
             * Возвращает значение всплывающей подсказки для элемента в расписании.
             * @return {String} Значение всплывающей подсказки для элемента в расписании.
             */
            getScheduleItemHint: function() {
                var timeFormat = Terrasoft.Resources.CultureSettings.timeFormat;
                var startDate = Ext.Date.format(this.get("StartDate"), timeFormat);
                var dueDate = Ext.Date.format(this.get("DueDate"), timeFormat);
                var title = this.get("Title");
                var account = this.get("Account");
                var accountDisplayValue = (account) ? account.displayValue + ": " : "";
                return Ext.String.format("{0}-{1} {2}{3}", startDate, dueDate, accountDisplayValue, title);
            },
 
            /**
             * Возвращает статус элемента расписания.
             * @return {Terrasoft.ScheduleItemStatus} Статус элемента расписания.
             */
            getScheduleItemStatus: function() {
                var isFinished = this.get("Status.Finish");
                var dueDate = this.get("DueDate");
                if (dueDate <= new Date() && !isFinished) {
                    return Terrasoft.ScheduleItemStatus.OVERDUE;
                } else if (isFinished) {
                    return Terrasoft.ScheduleItemStatus.DONE;
                }
                return Terrasoft.ScheduleItemStatus.NEW;
            },
 
            /**
             * Возвращает значение заголовка элемента в расписании.
             * @return {String} Значение заголовка элемента в расписании.
             */
            getScheduleItemTitle: function() {
                var title = this.get("Title");
                var account = this.get("Account");
                var accountDisplayValue = (account) ? account.displayValue + ": " : "";
                return Ext.String.format("{0}{1}", accountDisplayValue, title);
            },
 
            /**
             * inheritdoc Terrasoft.BaseGridRowViewModel#getEntitySchemaQuery
             */
            getEntitySchemaQuery: function() {
                var esq = this.callParent(arguments);
                if (!esq.columns.contains("Status.Finish")) {
                    esq.addColumn("Status.Finish");
                }
                return esq;
            },
 
            /**
             * inheritdoc Terrasoft.BaseViewModel#setColumnValues
             */
            setColumnValues: function(entity) {
                this.set("Status.Finish", entity.get("Status.Finish"));
                this.callParent(arguments);
            },
 
            /**
             * Обрабатывает событие изменения поля "Начало".
             * @protected
             * @param {Date} date Новое значение даты.
             */
            onStartDateChanged: function(date) {
                this.set("StartDate", date);
                this,
                this.saveEntity(Terrasoft.emptyFn, this);
            },
 
            /**
             * Обрабатывает событие изменения поля "Завершение".
             * @protected
             * @param {Date} date Новое значение даты.
             */
            onDueDateChanged: function(date) {
                this.set("DueDate", date);
                this.saveEntity(Terrasoft.emptyFn, this);
            },
 
            /**
             * Обрабатывает событие изменения поля "Заголовок".
             * @protected
             */
            onTitleChanged: Terrasoft.emptyFn,
 
            /**
             * Обрабатывает событие изменения поля "Состояние".
             * @protected
             */
            onStatusChanged: Terrasoft.emptyFn,
            getBackground: function() {
                var priority = this.get("Priority");
                var activitySchedulerColor = ActivitySectionGridRowHelper.GetActivitySchedulerColor(priority.value);
                var backgroundColor = activitySchedulerColor.backgroundColor;
                return backgroundColor;
            },
            getFontColor: function() {
                var priority = this.get("Priority");
                var activitySchedulerColor = ActivitySectionGridRowHelper.GetActivitySchedulerColor(priority.value);
                var fontColor = activitySchedulerColor.fontColor;
                return fontColor;
            }
        });
 
        return Terrasoft.ActivitySectionGridRowViewModel;
    });

Результат

В результате должно получится что-то вроде:

Для активности «Развернуть стенд» указан приоритет для которого не указан цвет в справочнике ActivitySchedulerColor. Соответственно, для него работает стандартная логика и он окрашивается в соответствии со своим статусом и временем.
Для приоритетов активностей «Позвонить клиенту» и «Написать Hello, World!» в справочнике ActivitySchedulerColor указан цвет, и они окрашиваются по добавленной логике.

Добрый день.

При реализации данного таска на шаге:

Шаг 4. Замещение модуля ActivitySectionGridRowViewModel.

появилась ошибка: "Замещение модулей запрещено".

Хотя в настройке модуля параметр "Запретить замещение" не установлен.

Можете подсказать, в чём может быть причина?

С 2016 года архитектура системы изменилась. Модули замещать запрещено, начиная с версии 7.13.1.

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

Подскажите, пожалуйста, как добавить свойство ENUM для справочника который находится в детали с редактируемым реестром. (рис.1)

Нравится

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

Подскажите пожалуйста. Просто добавить свойсвто Enum на страницу детали не работает.

Добрый день!

В детали с редактируемым реестром свойства редактируемого реестра настраиваются в секции "values": {}
Здесь описываются свойства listedConfig": {} и/или "tiledConfig": {}, где в массиве "items": [] описываются отображаемые в гриде колонки, например вот так:

"items": [{
"name": "AttributeListedGridColumn",
"bindTo": "Attribute",
"type": Terrasoft.GridCellType.LOOKUP,
"position": {
"column": 1,
"colSpan": 16
}
}]

Для того, чтобы справочное поле объекта (не виртуальное) отображалось выпадающим списком, нужно заместить соответствующий объект, в замещенном объекте настроить отображение нужного справочного поля в виде списка. Для этого открыть замещенный объект для редактирования и для выбранной колонки типа "Справочник" установить галочку напротив "Список".
Исходя из представленного скриншота, Вы хотите сделать именно это.
Свойство ENUM имеет смысл добавлять, если в дальнейшем предполагается работать со значениями из справочника, как с константами.

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

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

Здравствуйте. Случайно удалил деталь Адрес доставки из раздела Заказы. Теперь не могу вернуть эту деталь обратно. Помогите пожалуйста восстановить данную деталь
Благодарю

Нравится

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

Дмитрий, если Вы удалили деталь в мастере, то для восстановления достаточно открыть замещенную схему «OrderPageV2» и в секции diff убрать операцию «remove» соответствующей детали (см. скриншот).

"Вильшанский Дмитрий" написал:

Дмитрий, если Вы удалили деталь в мастере, то для восстановления достаточно открыть замещенную схему «OrderPageV2» и в секции diff убрать операцию «remove» соответствующей детали (см. скриншот).

Здравствуйте, Дмитрий.
Большое спасибо за помощь. Деталь вернулась обратно.
Благодарю

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

Происходит после создания нового объекта и наследования от базового справочника. Как исправить?

Нравится

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

Добрый день!
При 1-м входе пользователя в BPM открывается окно с показом видеоролика. Можно ли как-нибудь сделать самому похожее окно со своим содержимым и показать его пользователю?

Нравится

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

Если вас интересует полноэкранное окно с видео, как при первом старте системы, то почитайте схему «WelcomeScreen» в конфигурации. И её вызов в схеме ConfigurationViewModule, метод loadWelcomeScreen.
Если вас интересует просто модальное окно, с любым содержимым, посмотрите в эту тему: http://www.community.terrasoft.ru/forum/topic/17970#comment-63544

"Максим Шевченко" написал:

Если вас интересует полноэкранное окно с видео, как при первом старте системы, то почитайте схему «WelcomeScreen» в конфигурации. И её вызов в схеме ConfigurationViewModule, метод loadWelcomeScreen.

Если вас интересует просто модальное окно, с любым содержимым, посмотрите в эту тему: http://www.community.terrasoft.ru/forum/topic/17970#comment-63544


Спасибо!

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

ПРиветствую, не силен в js, подскажите как заполнить выходные дни на 3 года вперед, вот кусок кода, который делает это на текущий год.

//-----------------------------------------------------------------------------
// wnd_CalendarCelebrateGridAreaScript
//-----------------------------------------------------------------------------


function btnAddCelebrateOnClick(Control) {
        var Dataset = Services.GetNewItemByUSI('ds_CalendarCelebrate');
        var A = new Date();
        A.set
        var CurretYear = A.getYear();
        while (A.getYear() ==  CurretYear) {
                if ((A.getDay() == 0) || (A.getDay() == 6)) {
                        Dataset.Append();
                        Dataset.Values('Date') = ExtractDate(A).getVarDate();
                        Dataset.Values('Name') = 'Выходной';   
                        Dataset.Post();
                }
                A.setDate(A.getDate() +1)
        }
        Dataset.Close();
        dlData.Dataset.Close();
        dlData.Dataset.Open();    
}

Спасибо!

Нравится

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

Возможно, стоит поменять фрагмент:

 while (A.getYear() ==  CurretYear) {

на:

 while (A.getYear() <=  CurretYear + 3) {

Пробовал, так он не выполняет ничего при нажатии на кнопку.

Обманул Вас, надо было перезапустить клиентское приложение.
Спасибо!!!

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