Добрый день!

Столкнулся со свойством "Виртуальный" в объекте в блоке "Поведение".

Подскажите, пожалуйста, зачем это свойство нужно? Что происходит при его простановке в объекте? Либо, поделитесь ссылкой на документацию. Самостоятельно не удалось найти.

 

 

Нравится

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

Эдуард Р,

прекрасный пример - BaseProductEntity. В нём описана вся структура и логики типовой работы с продуктами в разных объектах.

А уже на основании этого виртуального объекта сделаны реальные - "продукт в счёте", "продукт в заказе", которые просто всё наследуют от базового.

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

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

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

Эдуард Р пишет:

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

Представление в базе данных, когда у нас нет объекта в базе данных, но view, а на основе view нужно сделать объект в creatio (объект будет только на чтение). Название view и колонок во view должно совпадать с название в конфигураторе.

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

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

Эдуард Р,

прекрасный пример - BaseProductEntity. В нём описана вся структура и логики типовой работы с продуктами в разных объектах.

А уже на основании этого виртуального объекта сделаны реальные - "продукт в счёте", "продукт в заказе", которые просто всё наследуют от базового.

Владимир Соколов,

понял, спасибо!

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

Здравствуйте. Столкнулся с проблемой следующего рода:
Появилась необходимость добавить действие на страницу редактирования активности.
Выполнил все пункты согласно инструкции на https://academy.terrasoft.ru/documents/technic-sdk/7-7/dobavlenie-deystviya-na-stranicu-redaktirovaniya . 
В результате получилась вот такая замещающая страница:

define("ActivityPageV2", ["ProcessModuleUtilities", "AbrConstants"],
    function(ProcessModuleUtilities, AbrConstants) {
        return {
            // Название схемы объекта страницы редактирования.
         entitySchemaName: "Activity",
         methods: {
          // Проверяет, в каком состоянии активность.
          isRunningMail: function() {
                if (this.get("Status") && this.get("Result")) {
                 return (this.get("Status").value === AbrConstants.Activity.State.Completed && this.get("Result").value === "632afdd2-f616-4ea6-87d2-8ed38eed8aff");
                }
                return false;
               },
            // Метод-обработчик действия.
          showActionInfo: function() {
                var args = {
                  sysProcessName: "SendEmailAboutTheApproval",
                  scope: this
                 };
                ProcessModuleUtilities.executeProcess(args);
                this.showInformationDialog("Оповещения в ДТ и ОД отправлены.");
               },
            // Переопределение базового виртуального метода, возвращающего коллекцию действий страницы редактирования.
          getActions: function() {
                // Вызывается родительская реализация метода для получения
                // коллекции проинициализированных действий базовой страницы.
                var actionMenuItems = this.callParent(arguments);
                // Добавление линии-разделителя.
                actionMenuItems.addItem(this.getButtonMenuItem({
                 Type: "Terrasoft.MenuSeparator",
                 Caption: ""
                }));
                // Добавление пункта меню в список действий страницы редактирования.
                actionMenuItems.addItem(this.getButtonMenuItem({
                    // Привязка заголовка пункта меню к локализуемой строке схемы.
                 "Caption": {bindTo: "Resources.Strings.SendEmailToOdAndDt"},
                    // Привязка метода-обработчика действия.
                 "Tag": "showActionInfo",
                    // Привязка свойства доступности пункта меню к значению, которое возвращает метод isRunning().
                 "Enabled": {bindTo: "isRunningMail"}
                }));
                return actionMenuItems;
               }
         }
        };
       }
);

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

Но если просто обновить страницу, кнопка становится активна.

В чем может быть причина?

Нравится

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

stique,

//PageV2
attributes: {
//На пейдже первым делом объявляю атрибут
//на который я буду биндить (байндить) свойство "enabled" кнопки
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляю сообщение с направлением PUBLISH, которое будем отправлять на секцию
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.PUBLISH
 }
},
methods: {
//Объявляю метод, который буду запускать два раза
//При инициализации страницы и после сохранения
//Он проставляет атрибут для кнопки 
//и одновременно отправляет сообщение с текущим статусом на секцию
//Хотя здесь можно сделать лучше и отправлять не статус, а непосредственно значение true/false
 getOrderButtonStatus: function() {
  this.sandbox.publish("GetOrderButtonStatus", this.get("UsrStatus"), [this.sandbox.id]);
  var status = this.$UsrStatus;
  if (status && status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 },
 onEntityInitialized: function() {
  this.callParent(arguments);
//вызываем первый раз
  this.getOrderButtonStatus();
 },
 onSaved: function() {
  this.callParent(arguments);
//вызываем второй раз
  this.getOrderButtonStatus();
 }
},
diff: [
//У меня была обычная кнопка на карточке, у Вас в меню Действия
//Так что Вам нужно забиндить кнопку на атрибут в Вашем методе getActions()
 {
  "operation": "insert",
  "name": "creatingOrderButton",
  "values": {
   "itemType": 5,
   "caption": "Create order",
   "click": {
    "bindTo": "syncCreatingOrder"
   },
   "style": "green",
   "enabled": {
    "bindTo": "isOrderButtonEnabled"//забиндить на атрибут
   },
   "classes": {
    "textClass": "actions-button-margin-right"
   }
  },
  "parentName": "LeftContainer",
  "propertyName": "items",
  "index": 7
 }
]
 
 
 
 
 
//SectionV2
attributes: {
//Здесь объявляем такой же атрибут
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляем такое же сообщение с направлением SUBSCRIBE
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.SUBSCRIBE
 }
},
methods: {
//в init подписываемся на нужное нам сообщение
//и если оно к нам приходит - запускается метод getOrderStatusButton
//Опять таки, здесь можно и нужно логику переделать, чтобы получать сразу значение true/false
//вместо статуса
 init: function() {
  this.callParent(arguments);
  this.sandbox.subscribe("GetOrderButtonStatus", function(value) { this.getOrderButtonStatus(value); }, this, [this.getCardModuleSandboxId()]);
 },
 getOrderButtonStatus: function(status) {
  if (status && status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 }
}

 

Насколько я понимаю и помню, то добавив действие на ActivityPageV2, это действие по-моему создается автоматически и в секции, средствами сообщений, я давно это тестил, уже не помню. В общем, в первом случае у вас кнопка ДЕЙСТВИЯ находится на ActivitySectionV2, а во втором случае кнопка ДЕЙСТВИЯ находится на ActivityPageV2, это две разные кнопки. И на пейдже у вас есть метод isRunningMail(), но на секции его нет. Вам нужно организовать передачу сообщения с пейджи на секцию какой там статус и результат, потому что на секции этой информации нет. У Вас случайно ошибки в консоль не сыпятся, когда вы открываете первый раз активность в совмещенном режиме? Я надеюсь, что хоть немного понятно изъяснился)) I'm doing my best)

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

Alex Zaslavsky,

Нет, ошибок в консоли нет.

Может быть я путаю, но кажется, когда мы открываем задачу, ActivityPage сразу подгружается.

stique,

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

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

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

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

Alex Zaslavsky,

Кажется Вы правы! Как правильно поступить в таком случае?

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

А где про этот механизм можно почитать? 

stique,

С механизмом сообщений знакомы? Sandbox

Я биндил свойство enabled на атрибут, на пейдже в методах onEntityInitialized и onSaved я отправлял сообщения на секшн и в зависимости от условий проставлял такой же атрибут в true или false.

Если нужно прям подробно, то могу позже описать полностью как я сделал.

Alex Zaslavsky,

Alex Zaslavsky пишет:
С механизмом сообщений знакомы? Sandbox

Увы нет, только неделю  как изучаю bpm)

Alex Zaslavsky пишет:
Если нужно прям подробно, то могу позже описать полностью как я сделал.

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

stique,

//PageV2
attributes: {
//На пейдже первым делом объявляю атрибут
//на который я буду биндить (байндить) свойство "enabled" кнопки
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляю сообщение с направлением PUBLISH, которое будем отправлять на секцию
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.PUBLISH
 }
},
methods: {
//Объявляю метод, который буду запускать два раза
//При инициализации страницы и после сохранения
//Он проставляет атрибут для кнопки 
//и одновременно отправляет сообщение с текущим статусом на секцию
//Хотя здесь можно сделать лучше и отправлять не статус, а непосредственно значение true/false
 getOrderButtonStatus: function() {
  this.sandbox.publish("GetOrderButtonStatus", this.get("UsrStatus"), [this.sandbox.id]);
  var status = this.$UsrStatus;
  if (status && status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 },
 onEntityInitialized: function() {
  this.callParent(arguments);
//вызываем первый раз
  this.getOrderButtonStatus();
 },
 onSaved: function() {
  this.callParent(arguments);
//вызываем второй раз
  this.getOrderButtonStatus();
 }
},
diff: [
//У меня была обычная кнопка на карточке, у Вас в меню Действия
//Так что Вам нужно забиндить кнопку на атрибут в Вашем методе getActions()
 {
  "operation": "insert",
  "name": "creatingOrderButton",
  "values": {
   "itemType": 5,
   "caption": "Create order",
   "click": {
    "bindTo": "syncCreatingOrder"
   },
   "style": "green",
   "enabled": {
    "bindTo": "isOrderButtonEnabled"//забиндить на атрибут
   },
   "classes": {
    "textClass": "actions-button-margin-right"
   }
  },
  "parentName": "LeftContainer",
  "propertyName": "items",
  "index": 7
 }
]
 
 
 
 
 
//SectionV2
attributes: {
//Здесь объявляем такой же атрибут
 "isOrderButtonEnabled": {
  "value": false
 }
},
messages: {
//Объявляем такое же сообщение с направлением SUBSCRIBE
 "GetOrderButtonStatus": {
  mode: Terrasoft.MessageMode.PTP,
  direction: Terrasoft.MessageDirectionType.SUBSCRIBE
 }
},
methods: {
//в init подписываемся на нужное нам сообщение
//и если оно к нам приходит - запускается метод getOrderStatusButton
//Опять таки, здесь можно и нужно логику переделать, чтобы получать сразу значение true/false
//вместо статуса
 init: function() {
  this.callParent(arguments);
  this.sandbox.subscribe("GetOrderButtonStatus", function(value) { this.getOrderButtonStatus(value); }, this, [this.getCardModuleSandboxId()]);
 },
 getOrderButtonStatus: function(status) {
  if (status && status.value === "caae507b-ccea-4275-967e-bb4f4c73a880") {
   this.set("isOrderButtonEnabled", true);
  }
  else {
   this.set("isOrderButtonEnabled", false);
  }
 }
}

 

Alex Zaslavsky,

Ого, большое спасибо Вам за такой развернутый ответ.
Еще нашел информацию что можно использовать "reloadAll: true", но пока не знаю как это прикрутить)

 

stique,

Отпишитесь потом, получилось или нет :)

Alex Zaslavsky,

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

stique,

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

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

Добрый день! 

Задача -  задать полю Примечание свойство, чтобы оно было всегда в режиме "без форматирования".

Подскажите пжлст, какое свойство отвечает за этот параметр?

 

Благодарю!

 

Нравится

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

Насколько понимаю такого свойства нет, но что мешает заместить вам детель и вместо поля примечания вставить свое многострочное поле ввода?

Насколько понимаю такого свойства нет, но что мешает заместить вам детель и вместо поля примечания вставить свое многострочное поле ввода?

Ну если я правильно понял, то нужно выбрать последний элемент, среди компонентов форматирования, можно сделать например так:

$(document).bind("DOMNodeInserted", function(e) {
if (e.target.id === "cke_ContactPageV2NotesHtmlEdit-html-edit-textarea") {
	var tabs = Ext.getElementById("ContactPageV2NotesHtmlEdit-html-edit-toolbar");
 
	var elem = Ext.get(tabs.children[9]);
	elem.dom.children[1].className = "t-btn-wrapper t-btn-no-text-padding t-btn-style-default t-btn-pressed";
 
}
}.bind(this));

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

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

Здравствуйте, можно ли в коде js программно изменять свойства объектов (интересует "обязательно для заполнения", "visible" и "enabled") не прибегая к bind или rules, т.е. делать это напрямую?

Нравится

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

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

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

Здравствуйте, Александр.

Для настройки логики полей в bpm'online 7.3 необходимо использовать бизнес-правила. Секция rules: на странице.

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

Здравствуйте!
Разъясните, пожалуйста, как изменить определенные свойства объектов на странице раздела из кода js (visible, dependencies и т.д). ? Нужно на ините проставить зависимости и спрятать некоторые поля, унаследованные от родителя. Заранее спасибо.

Нравится

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

необходимо программно изменить свойства объекта

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

Добрый день!
Вопрос следующий, можно ли из скрипта элемента процесса "Задача" изменять свойства полей той задачи которая будет использоваться?
Т.е. в обработчике события OnAfterExecute элемента "Задача" я бы хотел изменять свойства IsReadOnly или IsVisible некоторых полей.
Возможно ли такое ?
Если нет то какие варианты можете предложить кроме использования элементов DataEdit и Datatransfer?

Нравится

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

Андрей, в обработчике события OnAfterExecute это вряд ли получится, так как в этот момент карточка задачи уже сформирована и открыта. Можно попробовать реализовать следующую схему: при обработке события OnBeforeExecute элемента процесса устанавливать значение некоторого параметра (в котором, например, сохранять список названий полей для изменения), потом в OnExecute скрипта элемента процесса анализировать его значение и передавать с помощью атрибутов в скрипт окна редактирования, и уже в скрипте окна редактирования при обработке OnPrepare анализировать значение переданного атрибута (если задача является элементом процесса) и в зависимости от его значения изменять свойства контролов.

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

Если Вы успели заметить, в версии приложения Terrasoft CRM 3.3 появилось новое свойство грида CheckBoxDataFieldName. Наверняка, пользователю, плотно столкнувшемуся с разработкой дополнительных функциональностей, не является интуитивно понятным значение этого свойства. 
Итак, позвольте поясню.

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

Желаю удачи!

С уважением,
Мельникова Екатерина

Нравится

Поделиться

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