Добрый день!

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

Спасибо!Изображение удалено.

Нравится

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

Добрый день.

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

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

Доброго дня!

 

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

 

Есть предположение, что нужно как-то грамотно организовать колбэки с this.reloadGridData(), но никак не выходит. Может кто сталкивался с подобным кейсом

 

Исходный код прилагаю.

addRecord: function(typeColumnValue) {
    var config = {
	    recordId: Terrasoft.GUID_EMPTY,
		operation: Terrasoft.ConfigurationEnums.CardOperation.ADD,
		entitySchemaName: "Account",
		valuePairs: this.getAddMiniPageDefaultValues(),
		miniPageSchemaName: "AccountMiniPage",
	};
    this.openMiniPage(config);
},
 
getAddMiniPageDefaultValues: function() {
    var defaultValues = [];
    defaultValues.push({
        name: "Parent", 
        value: this.get("MasterRecordId")
    });
	defaultValues.push({
	    name: "Category",
		value: "dc199b6d-e948-4598-8a12-c38ca90428d8"
	});
	return defaultValues;
}

Благодарю за ваши ответы

Нравится

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

Вадим, добрый день

У вас деталь - это один модуль, а миникарточка - другой. Единственный вариант общения между модулями - это сообщения. И да, при  работе с этой миникарточкой вы всегда будете отправлять сообщение, а вот реагировать на него будет деталь только в том случае, если этот модуль сейчас загружен в системе (фактически, если он отображается на экране)

Вадим, добрый день.

 

Попробуйте реализовать нужный Вам функционал через обмен сообщениями песочницы. Более подробно об этом можно почитать в статье на Академии.

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

Спасибо за ответ! Однако реализация не совсем очевидна. Неужели для реализации этого кейса придется постоянно публиковать сообщение со стороны добавляемого объекта для обновления детали? Учитывая то, что добавляемый объект, помимо детали, может создаваться и из других мест

Вадим, добрый день

У вас деталь - это один модуль, а миникарточка - другой. Единственный вариант общения между модулями - это сообщения. И да, при  работе с этой миникарточкой вы всегда будете отправлять сообщение, а вот реагировать на него будет деталь только в том случае, если этот модуль сейчас загружен в системе (фактически, если он отображается на экране)

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

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

Создал объект: UsrCaseTest

  1. В этом объекте создал справочное поле UsrContact( родительский объект "Contact")
  2. Через мастера все добавил, настроил. Деталь работает справочное поле все показывает,

    Изображение удалено.
  3. После добавления значения не сохраняются. 

    Изображение удалено.
  4. Код схемы детали: 

     

    // Определение схемы и установка ее зависимостей от других модулей.

    define("UsrCaseTestDetail", ["ConfigurationEnums"],

        function(configurationEnums) {

            return {

                // Название схемы объекта детали.

                entitySchemaName: "UsrCaseTest",

                // Методы схемы детали.

                methods: { 

                    //Возвращает колонки, которые выбираются запросом.

                    getGridDataColumns: function() {

                        return {

                            "Id": {path: "Id"},

                            "UsrContact": {path: "UsrContact"},

                            "UsrContact.Name": {path: "UsrContact.Name"}

                        };

                    },

                    openContactLookup: function() {

                        var config = {

                            entitySchemaName: "Contact",

                            multiSelect: true,

                            columns: ["Name"]

                        };

                        // Экземпляр класса [EntitySchemaQuery].

                        var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {

                            // Установка корневой схемы.

                            rootSchemaName: this.entitySchemaName

                        });

                        // Добавление колонки [Id].

                        esq.addColumn("Id");

                        // Добавление колонки [Id] из схемы [Document].

                        esq.addColumn("UsrContact.Id", "UsrContactId");

                        esq.getEntityCollection(function(result) {

                            var existsContactsCollection = [];

                            if (result.success) {

                                result.collection.each(function(item) {

                                    existsContactsCollection.push(item.get("UsrContactId"));

                                });

                            }

                            // Добавление фильтра в конфигурационный объект.

                            if (existsContactsCollection.length > 0) {

                                var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",

                                existsContactsCollection);

                                existsFilter.comparisonType = this.Terrasoft.ComparisonType.NOT_EQUAL;

                                existsFilter.Name = "existsFilter";

                                config.filters = existsFilter;

                            }

                            // Вызов модального окна справочника

                            this.openLookup(config, this.addCallBack, this);

                        }, this);

                    },

                    // Обработчик события сохранения страницы редактирования.

                    onCardSaved: function() {

                        this.openContactLookup();

                    },

                    //Открывает справочник документов в случае если страница редактирования заказа была ранее сохранена.

                    addRecord: function() {

                        var masterCardState = this.sandbox.publish("GetCardState", null, [this.sandbox.id]);

                        var isNewRecord = (masterCardState.state === configurationEnums.CardStateV2.ADD ||

                        masterCardState.state === configurationEnums.CardStateV2.COPY);

                        if (isNewRecord === true) {

                            var args = {

                                isSilent: true,

                                messageTags: [this.sandbox.id]

                            };

                            this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);

                            return;

                        }

                        this.openContactLookup();

                    },

                    // Добавление выбранных продуктов.

                    addCallBack: function(args) {

                        // Экземпляр класса пакетного запроса BatchQuery.

                        var bq = this.Ext.create("Terrasoft.BatchQuery");

                        // Коллекция выбранных в справочнике документов.

                        this.selectedRows = args.selectedRows.getItems();

                        // Коллекция, передаваемая в запрос.

                        this.selectedItems = [];

                        // Копирование необходимых данных.

                        this.selectedRows.forEach(function(item) {

                            item.UsrContactId = item.value;

                            bq.add(this.getDocumentInsertQuery(item));

                            this.selectedItems.push(item.value);

                        }, this);

                        // Выполнение пакетного запроса, если он не пустой.

                        if (bq.queries.length) {

                            this.showBodyMask.call(this);

                            bq.execute(this.onContactInsert, this);

                        }

                    },

                    //Возвращает запрос на добавление текущего объекта.

                    getDocumentInsertQuery: function(item) {

                        var insert = Ext.create("Terrasoft.InsertQuery", {

                            rootSchemaName: this.entitySchemaName

                        });

                        insert.setParameterValue("UsrContact", item.UsrContactId, this.Terrasoft.DataValueType.GUID);

                        return insert;

                    },

                    // Метод, вызываемый при добавлении записей в реестр детали.

                    onContactInsert: function(response) {

                        this.hideBodyMask.call(this);

                        this.beforeLoadGridData();

                        var filterCollection = [];

                        response.queryResults.forEach(function(item) {

                            filterCollection.push(item.id);

                        });

                        var esq = Ext.create("Terrasoft.EntitySchemaQuery", {

                            rootSchemaName: this.entitySchemaName

                        });

                        this.initQueryColumns(esq);

                        esq.filters.add("recordId", Terrasoft.createColumnInFilterWithParameters("Id", filterCollection));

                        esq.on("createviewmodel", this.createViewModel, this);

                        esq.getEntityCollection(function(response) {

                            this.afterLoadGridData();

                            if (response.success) {

                                var responseCollection = response.collection;

                                this.prepareResponseCollection(responseCollection);

                                this.getGridData().loadAll(responseCollection);

                            }

                        }, this);

                    },

                    // Метод, вызываемый при удалении выбранных записей детали.

                    deleteRecords: function() {

                        var selectedRows = this.getSelectedItems();

                        if (selectedRows.length > 0) {

                            this.set("SelectedRows", selectedRows);

                            this.callParent(arguments);

                        }

                    },

                    // Скрыть пункт меню [Копировать].

                    getCopyRecordMenuItem: Terrasoft.emptyFn,

                     // Скрыть пункт меню [Изменить].

                    getEditRecordMenuItem: Terrasoft.emptyFn,

                    // Возвращает имя колонки по умолчанию для фильтра.

                    getFilterDefaultColumnName: function() {

                        return "UsrContact";

                    }

                },

                // Массив модификаций.

                diff: /**SCHEMA_DIFF*/[

                    {

                        // Тип операции — слияние.

                        "operation": "merge",

                        // Название элемента схемы, над которым производится действие.

                        "name": "DataGrid",

                        // Объект, свойства которого будут объединены со свойствами элемента схемы.

                        "values": {

                            "rowDataItemMarkerColumnName": "UsrContact"

                        }

                    },

                    {

                        // Тип операции — слияние.

                        "operation": "merge",

                        // Название элемента схемы, над которым производится действие.

                        "name": "AddRecordButton",

                        // Объект, свойства которого будут объединены со свойствами элемента схемы.

                        "values": {

                            "visible": {"bindTo": "getToolsVisible"}

                        }

                    }

                ]/**SCHEMA_DIFF*/

            };

        }

    );

  5. Код карточки контакта: define("ContactPageV2", [], function() {

        return {

            entitySchemaName: "Contact",

            attributes: {},

            modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,

            details: /**SCHEMA_DETAILS*/{

                "UsrCaseDetail": {

                    "schemaName": "UsrCaseTestDetail",

                    "entitySchemaName": "UsrCaseTest",

                    "filter": {

                        "detailColumn": "UsrContact",

                        "masterColumn": "Id"

                    }

                }

            }/**SCHEMA_DETAILS*/,

            businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,

            methods: {},

            dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,

            diff: /**SCHEMA_DIFF*/[****]/**SCHEMA_DIFF*/};

Нравится

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

Ислам Ибрагимжанов,

У вас деталь (UsrCaseTest) привязана к карточке Контактов (Contact) по полю UsrContact.

Допустим, вы находитесь в карточке ИвановИван

Выбирая в вашем справочнике значения - вы в базу пишете в ту же колонку UsrContact значения, которые выбрали, допустим вы выбрали 2 значения ПетровПетр и СидоровСидр.

Итого у вас в табличке UsrCaseTest запишутся значения:

ПетровПетр и СидоровСидр

 

Как вы хотите чтобы они отобразились в вашей карточке ИвановИван? У вас на детали стоит фильтр - отображать из таблицы UsrCaseTest те записи, в поле UsrContact лежит Id текущей записи - ИвановИван. Добавленные же записи вы сможете увидеть в карточке ПетровПетр или СидоровСидр (в соответствии с фильтром).

 

Чтобы все работало верно - посмотрите еще раз пример на академии.

Вам нужно 2 поля. Первое - связь с карточкой - по нему у вас привязана деталь UsrContact. Второе - в которое должны складываться выбранные значения. Пусть будет UsrSelectedContact. Исправляете в коде методы которые я говорил - и должно работать

Судя по коду, вы забываете заполнять колонку связи с вашим объектом (основной карточкой). Обратите внимание на функцию getDocumentInsertQuery в примере. Там заполняются 2 поля:

UsrOrder //связь с карточкой
UsrDocument // документ (то что выбираем из справочника)

 

Также обратите внимание на функцию addCallBack. В ней как раз и прокидывают поле связи с карточкой. Вы этот код также вырезали.

 

 

 

 

Fast traslate

 

Icon translate

 

 

 

Дмитрий Антохин,

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

Ислам Ибрагимжанов,

У вас деталь (UsrCaseTest) привязана к карточке Контактов (Contact) по полю UsrContact.

Допустим, вы находитесь в карточке ИвановИван

Выбирая в вашем справочнике значения - вы в базу пишете в ту же колонку UsrContact значения, которые выбрали, допустим вы выбрали 2 значения ПетровПетр и СидоровСидр.

Итого у вас в табличке UsrCaseTest запишутся значения:

ПетровПетр и СидоровСидр

 

Как вы хотите чтобы они отобразились в вашей карточке ИвановИван? У вас на детали стоит фильтр - отображать из таблицы UsrCaseTest те записи, в поле UsrContact лежит Id текущей записи - ИвановИван. Добавленные же записи вы сможете увидеть в карточке ПетровПетр или СидоровСидр (в соответствии с фильтром).

 

Чтобы все работало верно - посмотрите еще раз пример на академии.

Вам нужно 2 поля. Первое - связь с карточкой - по нему у вас привязана деталь UsrContact. Второе - в которое должны складываться выбранные значения. Пусть будет UsrSelectedContact. Исправляете в коде методы которые я говорил - и должно работать

Дмитрий Антохин,

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

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

Приветствую, коллеги!

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

Есть раздел "Номенклатура материалов" (рис.1). На основе этого раздела создал деталь с редактируемым реестром, по методике (https://academy.terrasoft.ru/docs/7-16/developer/elements_and_component…). Эту деталь вывел на раздел "Обращение" (рис.2). В деталь элементы добавляются и создаются сразу в разделе.

А как сделать так, чтобы при добавлении в делать в поле "Название" была возможность выбрать уже существующие материалы из раздела "Номенклатура материалов"?

 

Прикрепленные файлы

Нравится

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

Артур, добрый день!

 

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

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

Всем доброго дня.

Подскажите пожалуйста, как проще всего добавить номер по порядку при создании новой записи в детали через "+"? 

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

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

Нравится

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

Я делал автонумерацию через процесс на объекте. Триггер на срабатываение кода - после добавления записи или после удаления.

 

Код следующий, на сколько тут все хорошо не знаю, но вроде работает. Ручное переименование можно запретить, либо добавить "стрелочки" с перетаскиванием позиции вверх-вниз на клиенте.

 

using System.Linq;
 
public virtual void RunNumeration()
        {
            string parentEnityName = "UsrParent"; //Колонка с родителем, например Invoice для объекта InvoiceProduct
            var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, Entity.Schema.Name);
            var positionNumberColumn = esq.AddColumn("UsrPositionNumber").Name; //колонка с номером по порядку
            esq.AddAllSchemaColumns();
            if (parentEnityName.IsNotNullOrEmpty())
            {
                Guid parentEnityId = Entity.GetTypedColumnValue<Guid>(parentEnityName+"Id");
                if (parentEnityId != Guid.Empty)
                {
                    esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, parentEnityName, parentEnityId));
                    var entityProductsCollection = esq.GetEntityCollection(UserConnection)
		            .OrderBy(x => x.GetTypedColumnValue<int>(positionNumberColumn) == 0)
		            .ThenBy(x => x.GetTypedColumnValue<int>(positionNumberColumn));
		            int newNumber = 0;
		            foreach (var item in entityProductsCollection)
		            {
		                int number = item.GetTypedColumnValue<int>(positionNumberColumn);
		                newNumber++;
		                if (number != newNumber)
		                {
		                    item.SetColumnValue("UsrPositionNumber", newNumber);
		                    item.Save();
		                }
		            }
                }
            }
        }

 

Я делал автонумерацию через процесс на объекте. Триггер на срабатываение кода - после добавления записи или после удаления.

 

Код следующий, на сколько тут все хорошо не знаю, но вроде работает. Ручное переименование можно запретить, либо добавить "стрелочки" с перетаскиванием позиции вверх-вниз на клиенте.

 

using System.Linq;
 
public virtual void RunNumeration()
        {
            string parentEnityName = "UsrParent"; //Колонка с родителем, например Invoice для объекта InvoiceProduct
            var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, Entity.Schema.Name);
            var positionNumberColumn = esq.AddColumn("UsrPositionNumber").Name; //колонка с номером по порядку
            esq.AddAllSchemaColumns();
            if (parentEnityName.IsNotNullOrEmpty())
            {
                Guid parentEnityId = Entity.GetTypedColumnValue<Guid>(parentEnityName+"Id");
                if (parentEnityId != Guid.Empty)
                {
                    esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, parentEnityName, parentEnityId));
                    var entityProductsCollection = esq.GetEntityCollection(UserConnection)
		            .OrderBy(x => x.GetTypedColumnValue<int>(positionNumberColumn) == 0)
		            .ThenBy(x => x.GetTypedColumnValue<int>(positionNumberColumn));
		            int newNumber = 0;
		            foreach (var item in entityProductsCollection)
		            {
		                int number = item.GetTypedColumnValue<int>(positionNumberColumn);
		                newNumber++;
		                if (number != newNumber)
		                {
		                    item.SetColumnValue("UsrPositionNumber", newNumber);
		                    item.Save();
		                }
		            }
                }
            }
        }

 

Трефилов Павел Сергеевич, 

 

спасибо, отлично работает с вашим кодом)

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

Есть необходимость по галке в основной карточке делать деталь с редактируемым реестром(и) ТДЧ. 

Судя по публикациям здесь, в текущей версии бизнес-правилами это не реализуемо. 



В разработке на Creatio я недавно, поэтому творческие варианты решения данной задачи приходят со скрипом. На данный момент решение такое:

 

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



Или есть другие более удачные решения данной задачи? 




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

Нравится

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

Если отвечать на вопрос, то с помощью механизма сообщений.

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

Если отвечать на вопрос, то с помощью механизма сообщений.

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

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

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

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

Нравится

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

//в карточке

messages: {

    "Message1": {

        mode: this.Terrasoft.MessageMode.PTP,

        direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE

    }

},

methods: {

    this.sandbox.subscribe("Message1", function(args) {

        console.log(args);

    },this, ["Message1"]);

}

//в детали

messages: {

    "Message1": {

        mode: this.Terrasoft.MessageMode.PTP,

        direction: this.Terrasoft.MessageDirectionType.PUBLISH

    }

},

methods: {

    this.sandbox.publish("Message1", args, ["Message1"]);

}

//в карточке

messages: {

    "Message1": {

        mode: this.Terrasoft.MessageMode.PTP,

        direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE

    }

},

methods: {

    this.sandbox.subscribe("Message1", function(args) {

        console.log(args);

    },this, ["Message1"]);

}

//в детали

messages: {

    "Message1": {

        mode: this.Terrasoft.MessageMode.PTP,

        direction: this.Terrasoft.MessageDirectionType.PUBLISH

    }

},

methods: {

    this.sandbox.publish("Message1", args, ["Message1"]);

}

Показать все комментарии
//в diff
"ContractDetailV20ddfbca0": {
    "schemaName": "ContractDetailV2",
     "entitySchemaName": "Contract",
     "filter": {
        "detailColumn": "Account",
         "masterColumn": "Id"
    },   //не забываем здесь поставить запятую
    "filterMethod": "filtrationNrbFinApplicationDoubleDetail" // добавляем такую строчку. Название (справа) может быть любым.
},
 
//в методах
filtrationNrbFinApplicationDoubleDetail: function () {
	var filterGroup = new this.Terrasoft.createFilterGroup(); 
	filterGroup.add("ByIdFilter", this.Terrasoft.createColumnFilterWithParameter(
		this.Terrasoft.ComparisonType.NOT_EQUAL, "Id", this.get("Id"))
	);
	return filterGroup;
},

 

Нравится

Поделиться

0 комментариев
Показать все комментарии
define("NrbFinApplicationDoubleDetail", [], function() {
	return {
		entitySchemaName: "FinApplication",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			init: function(){
				this.callParent(arguments);
				var currentHistoryState = this.sandbox.publish('GetHistoryState');
				var recordId = currentHistoryState.hash.recordId;
				if(!Ext.isEmpty(recordId)){
 
				}
var masterRecordsValues =
                  	this.sandbox.publish("GetColumnsValues", ["NrbSubThema"], [this.sandbox.id]) || {};
			}
		}
	};
});

 

Нравится

Поделиться

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

Спасибо, то что я искал, а как передать из детали в карточку ?

В соседней теме уже ответили.

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

Добрый день!

 

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

 

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

 

Нравится

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

Что интересно, если открыть настройку колонок детали, то там в предпросмотре так, как Вы хотите.

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

Сходу нашёл, как смена стандартного word-wrap: normal на word-wrap: break-word; у [class*='grid-cols-'] меняет перенос по словам на перенос по буквам, но как сделать чтобы вообще без переноса, пока не нашёл. Может, у Вас выйдет.

Уже заведена и принята идея:

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

1. реестр раздела

2. списки в итогах

Но пока в планах на новые версии её нет.

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

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

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