Добрый день!

Подскажите, пожалуйста, можно ли сделать так чтобы значение справочного поля равнялось значению атрибута. Чтобы вопрос не казался странным, расскажу откуда растут корни. В атрибуте храниться значение Id продукта, который подбирается сложным, составным фильтром. Это значение надо передать в справочное поле продукта (привязанное к детали страницы), которое будет скрыто. Почему сделано так, потому что не смог реализовать комплексный фильтр к справочному полю детали (не нашел подходящего примера).

Нравится

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

А что мешает например при загрузке загрузить в справочник ваше значение атрибута и настроить чтоб при изменении атрибута менялось значения справочника или вам что-то другое нужно?  Обмен данными между страничкой и деталью можно через подписку на события реализовать.Таким событием может стать например изменение атрибута(виртуальной колонки)

Можете более подробно описать Вашу задачу (со скриншотами интерфейса пользователя), что и куда Вы хотите передавать?

Да. Вот моя страница подбора продукта.

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

Руслан Хасанов пишет:

На самом деле мне просто нужно сохранить подобранный продукт в детали

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

На самом деле хотелось бы просто передать значение Id продукта на клиентской схеме. Вариант прямого сохранения в объект детали используя запрос не удобен тем что:

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

2. Второе происходит из первого - надо проверять есть ли такой Id в детали, если да то йпдейт. 

3. Надо переопределить кнопку сохранения

4. Необходимо изобретать велосипед, т.е. повторять логику сохранения записи детали.

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

А что мешает например при загрузке загрузить в справочник ваше значение атрибута и настроить чтоб при изменении атрибута менялось значения справочника или вам что-то другое нужно?  Обмен данными между страничкой и деталью можно через подписку на события реализовать.Таким событием может стать например изменение атрибута(виртуальной колонки)

Да, Григорий, мне так и надо сделать, чтобы в значение справочника устанавливалось значение атрибута. Мешает недостаток опыта, я не могу найти пример кода как это сделать. Если есть возможность, приведите, пожалуйста, пример. Спасибо огромное!

Нашел ветку в которой обсуждалась данная тема https://community.terrasoft.ru/questions/znacenie-v-pole-spravocnik

Вот решение для этого вопроса: 

this.loadLookupDisplayValue("Type", constants.ContractType.Standard);

Большое спасибо Сергею за подсказку.

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

Всем доброго времени суток! Подскажите как отфильтровать значения в атрибуте, атрибут типа справочник

 В ActionDashBoard есть поле - http://prntscr.com/j49u8q

Реализовано оно следующим способом - http://prntscr.com/j49v2d, задал на данный атрибут фильтрацию, но она не срабатывает. Подскажите как реализовать фильтрацию данного атрибута?

пробовал через правила так же не работает.

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

 

Заранее спасибо.

Нравится

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

var countryId = this.get("Country") - Вы здесь получаете не айдишник, а объект. попробуйте в самом фильтре дописать - countryId.value

Alex Zaslavsky,

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

"Country": {

                        "dataValueType": Terrasoft.DataValueType.TEXT,

                        "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,

                        "value": ""

                    }

getCurrentContactCountry: function () {

                        var currentContactId = Terrasoft.SysValue.CURRENT_USER_CONTACT.value;

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

                            rootSchemaName: "Contact"

                        });

                        esq.addColumn("Country", "CountryId");

                        esq.getEntity(currentContactId, function(result) {

                            if (!result.success) {

                                this.showInformationDialog(Resources.localizableStrings.AbCurrentUserCountryError);

                                return;

                            }

                            var country = result.entity.get("CountryId");

                            if(country!== null || country!== undefined) {

                                this.set("Country", country.value);

                            }

                        },this)

                    }

У меня проблема в другом в функцию фильтрации даже и не заходит

Я не силен в этом, но попробуйте вместо - 

"filters": [

function()

написать - 

filter: function()

я, к примеру, у себя в лиде вот таким образом фильтрую поле "Партнер"

Alex Zaslavsky,​​​​​​

Благодарю. Подскажите, а UsrSourcePartner определен у Вас в лиде? Мой атрибут не определен в моем объекте. Я ссылаюсь на другой объект. Данное поле грубо говоря у меня одноразовое, достал id и передал на сервис. Может не срабатывать фильтрация если нет связи основного объекта с атрибутом?

Нигрескул Алексей,

Да, это определенное поле "Партнер" (справочник Контрагенты).

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

Коллеги нужна помощь, не работает фильтрация в атрибутах. Дополнительная информация клиентский модуль в котором реализую данный функционал, наследуется от BaseMessagePublisherPage ( MessagePublisher ), Может из-за этого не работать фильтрация?

Нигрескул Алексей пишет:

Коллеги нужна помощь, не работает фильтрация в атрибутах

Спрашивали - помогаю.

TLDR: террасофт факапнулся. В очередной раз. Убирите ContentType.ENUM. 

Теперь подробно (тестил на CallMessagePublisherPage. У вас я так понимаю аналог, ну да не важно):

1. Сделал фильтр, запустил, контакты отфильтровались

2. Раскомментировал contentType. ВНЕЗАПНО сортировка перестала работать.

3. Нет. Тот факт, что колонка виртуальная никак не влияет. тестил.



В итоге: я бы посоветовал посмотреть что творится в функции loadLookupData или др. функции которую, возможно, запускает enum. Честно говоря, устал воевать с ветряными мельницами. Сначала редактируемый реестр испоганили, теперь вот это...

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

Благодарю! Проверим.

Нигрескул Алексей пишет:

Благодарю! Проверим.

Я тут вспомнил, что уже сталкивался с таким поведением) BaseMessagePublisherPage не наследуется от BasePageV2, и из BasePageV2 не вызывается getLookupQuery. Чтобы исправить поведение ENUM-ов придётся ручками перекопировать функцию (и все вложеные в неё) на вашу страницу.

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

Благодарю! Все получилось! Так же сделал при добавлении нового элемента в маркетинговой кампании  - 

http://prntscr.com/j5wl4q

Работает - УРА!))

 

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

Я хочу изменить значение по умолчанию аттрибута IsReadOnly для окна выборки.
Я так понимаю это должно быть доступно в обработчике события OnPrepareSelectWindow LookupDataField, однако не смог разобраться как. все, что смог найти - это указать SelectWindowUSI и настроить LoockupDataset для окна выбора.

Нравится

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

Денис, этот атрибут задаётся в свойствах или датасета, или окна. Вот как он проверяется в скрипте scr_SelectData:

	var IsReadOnlyFromDataset = 
		GetAttribute(SelectData.Dataset, IsReadOnlyAttrName);
	var IsReadOnlyFromWindow = GetAttribute(Window, IsReadOnlyAttrName);
	SelectData.IsReadOnly = IsReadOnlyFromDataset || IsReadOnlyFromWindow;

А так он задаётся в обработчике OnPrepareSelectWindow в wnd_CampaignEditScript:

function edtOwnerOnPrepareSelectWindow(LookupDataControl) {
	PrepareLookupDataControl(LookupDataControl, dlData.Dataset);
}

Эта функция в scr_WindowUtils:

function PrepareLookupDataControl(LookupDataControl, Dataset) {
	var DataFieldName = LookupDataControl.DataFieldName;
	var DataField = Dataset.DataFields.ItemsByName(DataFieldName);
	var LookupDataset = DataField.LookupDataset;
	SetAttribute(LookupDataset, 'IsReadOnly', true);
}
Показать все комментарии

В исходных кодах часто встречается использование свойства initMethod, например

...
"Recommendation": {
        dataValueType: this.Terrasoft.DataValueType.MAPPING,
        type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
        caption: resources.localizableStrings.RecommendationCaption,
        initMethod: "initProperty",
        isRequired: false,
        doAutoSave: true
},
...

Но не совсем понятен смысл, и как его использовать в пользовательских атрибутах
(и можно ли вообще ?)
По идее этот метод должен вызываться при первичном инициализации значения аттрибута или нет ?

PS: Здравый смысл показывает что можно бы забиндить "value" атрибута на метод, для первичной инициализации - но

"value": {bindTo: "MyMethod"}

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

Нравится

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

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

Пример реализации и вызова функции указанного в атрибуте можете посмотреть в схеме ProcessFlowElementPropertiesPage.

Пример кода:

initParameters: function(element) {
	this.initDesignerType();
	Terrasoft.each(this.columns, function(columnConfig, columnName) {
		if (columnConfig.initMethod) {
			var parameter = element.findParameterByName(columnName);
			this[columnConfig.initMethod](parameter);
		}
	}, this);
},

Пример реализации метода:

initProperty: function(parameter) {
	var parameterName = parameter.name;
	this.set(parameterName, this.getParameterValue(parameter));
},

Метод initParameters вызовется в момент создании экземпляра схемы/модуля.

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

Зачастую в атрибуте объявляется целый перечень колонок
н/п

attributes: {
                        "UsrConfigProduct": {
                                lookupListConfig: {
                                        columns: [
                                                "UsrBrand",
                                                "UsrClass",
                                                "UsrProductType",
                                                "UsrProductCountry"
                                        ]
                                }
                        }
                }

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

Нравится

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

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

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

в окне редактирования (на базе baseDBEdit) добавляю windowcontainer и в нем гриди передаю атрибут

function InitializeOfferingWindow() {
        var Dataset = dlData.Dataset;
        var OfferingsWindow = wndOfferingsInContract.Window;
        SetAttribute(OfferingsWindow, 'AnnexID', Dataset('ID'));
        SetAttribute(OfferingsWindow, 'ContractID', Dataset('ContractID'));
        OfferingsWindow.Prepare();
}

function wnd_AnnexEditOnPrepare(Window) {
        wnd_BaseDBEditOnPrepare(Window);
        InitializeOfferingWindow();
}

получаю атрибут и передаю дальше

function wnd_OfferingInContractGridAreaOnPrepare(Window) {
        SetAttribute(Window, 'EditWindowUSI', 'wnd_OfferingInContractEdit');
        var AnnexID = Window.Attributes('AnnexID');
        var ContractID = Window.Attributes('ContractID');
        if (AnnexID != null) {
                var Dataset = dlData.Dataset;
                ApplyDatasetFilter(Dataset, 'AnnexID', AnnexID, true);
                SetAttribute(Dataset, 'AnnexID', AnnexID);
                SetAttribute(Dataset, 'ContractID', ContractID);
        }       RefreshDataset(Dataset);
}

ну и перед записью, хочу добавить в датасет

function SelfOnDatasetBeforePost(Dataset) {
        var AnnexID = Self.Attributes('AnnexID');
        if (AnnexID != null) {
                Dataset('AnnexID') = AnnexID;
                Dataset('ContractID') = Self.Attributes('ContractID');
        }
}

но он там null
хотя если смотреть в afteropen то он там есть

Нравится

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

"Змитрук Т.Ю." написал: SetAttribute(Dataset, 'ContractID1', ContractID);

Так у Вас же название атрибута который вы датасету передаете уже называются

ContractID1

прошу, прощения не правильно скопировал
исправил

Здравствуйте!
А что в функции SelfOnDatasetBeforePost возвращает Self?

"Андрей Каспаревич" написал:

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

А что в функции SelfOnDatasetBeforePost возвращает Self?

С уважением,

Каспаревич Андрей

Эксперт 3-й линии поддержки


а что именно надо?
к примеру
USI "Contracts\Details\Offerings\ds_OfferingInContract" String

В общем попробуйте вместо

var AnnexID = Self.Attributes('ContractID');

написать

var AnnexID = Dataset.Attributes('ContractID');

пробовал и так
результат тот же
в afterOpen
beforeopen есть ID
в beforepost - null

Непонятно к чему такой изобретательный путь.
Все что я понял, это то что у есть:
1) wnd_AnnexEdit - карточка, в ней получаем параметры AnnexID и ContractID
2) в ней грид wnd_OfferingInContractGridArea
3) (неизвестно)
4) И вдруг сразу записываете в датасет ds_OfferingInContract

Вот можно магию в пункте 3 описать?
Как вы записываете в датасет ds_OfferingInContract (в скобках последующий вопрос):
1) Реально сразу, как только грид подготовлен, так сразу пишем? (не вижу смыла добавлять параметры датасету, можно работать в этом окне, зачем параметры датасету?)
2) Через какую-то кнопку, которая обращается к датасету и пишет (как-то скриптово)? (не сильно от первого отлтчается "(не вижу смыла добавлять параметры датасету, можно работать в этом окне, зачем параметры датасету?)")
3) Через карточку wnd_OfferingInContractEdit? (А почему вы передаете параметры сразу датасету, а не карточке редактирования, а потом с ней не работаете?)

"Змитрук Т.Ю." написал:перед записью, хочу добавить в датасет

кстати, это датасет чего? карточки или грида? это как бы разные экземпляры...

"Сазанов Александр Владимирович" написал:

Непонятно к чему такой изобретательный путь.

Все что я понял, это то что у есть:

1) wnd_AnnexEdit - карточка, в ней получаем параметры AnnexID и ContractID

2) в ней грид wnd_OfferingInContractGridArea

3) (неизвестно)

4) И вдруг сразу записываете в датасет ds_OfferingInContract

Вот можно магию в пункте 3 описать?

Как вы записываете в датасет ds_OfferingInContract (в скобках последующий вопрос):

1) Реально сразу, как только грид подготовлен, так сразу пишем? (не вижу смыла добавлять параметры датасету, можно работать в этом окне, зачем параметры датасету?)

2) Через какую-то кнопку, которая обращается к датасету и пишет (как-то скриптово)? (не сильно от первого отлтчается "(не вижу смыла добавлять параметры датасету, можно работать в этом окне, зачем параметры датасету?)")

3) Через карточку wnd_OfferingInContractEdit? (А почему вы передаете параметры сразу датасету, а не карточке редактирования, а потом с ней не работаете?)


в пункте 3 пункт 3
через карточку wnd_OfferingInContractEdit выбираю продукт


кстати, это датасет чего? карточки или грида? это как бы разные экземпляры...

грида

Ну тогда передавайте параметры в карточку wnd_OfferingInContractEdit (а не вдатасет), точнее в ней на OnPrepare берите параметры из родительского окна (т.е. грида), а в датасет вставляйте значения, что-то типа так:

var ParentWindow = Self.Attributes('NotifyObject').ParentWindow; //Получаем наш грид
if (ParentWindow.Attributes('AnnexID')!=null) {
   dlData.Dataset('AnnexID') = ParentWindow.Attributes('AnnexID');
   dlData.Dataset('ContractID') = ParentWindow.Attributes('ContractID');
}

надо больше информации, т.к. не понятно, что на самом деле вы делаете

"Сазанов Александр Владимирович" написал:

Ну тогда передавайте параметры в карточку wnd_OfferingInContractEdit (а не вдатасет), точнее в ней на OnPrepare берите параметры из родительского окна (т.е. грида), а в датасет вставляйте значения, что-то типа так:

var ParentWindow = Self.Attributes('NotifyObject').ParentWindow; //Получаем наш грид

if (ParentWindow.Attributes('AnnexID')!=null) {

   dlData.Dataset('AnnexID') = ParentWindow.Attributes('AnnexID');

   dlData.Dataset('ContractID') = ParentWindow.Attributes('ContractID');

}


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

"Андросов Дмитрий" написал:

надо больше информации, т.к. не понятно, что на самом деле вы делаете


что конкретно надо?

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

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