Документация по разработке bpm’online
PDF

Добавление пользовательского перехода для нового элемента кампании

Glossary Item Box

Общие сведения

Для настройки маркетинговой кампании используется [Дизайнер кампании]. С его помощью можно создать визуальную схему кампании, состоящую из связанных предустановленных элементов. Также существует возможность создания пользовательских элементов кампании.

Общая последовательность добавления пользовательского перехода (стрелки):

  1. Создание новой схемы для элемента [Переход].
  2. Создание страницы редактирования свойств элемента [Переход].
  3. Создание серверной части элемента [Переход].
  4. Создание исполняемого элемента для перехода.
  5. Создание замещающего модуля CampaignConnectorManager для добавления логики работы перехода.
  6. Подключение замещающего модуля CampaignConnectorManager.

Описание примера

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

ВАЖНО

В этом примере в названиях схем отсутствует префикс Usr. Префикс, используемый по умолчанию, можно изменить в системной настройке [Префикс названия объекта] (код SchemaNamePrefix).

ВАЖНО

Перед выполнением примера выполните шаги 1-6 из статьи "Добавление пользовательского элемента кампании".

Исходный код

Пакет с реализацией примера можно скачать по ссылке.

Алгоритм выполнения примера

1. Создание объектов [Получатель СМС] и [Отклики по рассылке]

Для полноценной работы примера в пакете разработки создайте схемы объектов [Получатель СМС] ([TestSmsTarget]) (рис. 1) и [Отклики по рассылке] ([TestSmsResponseType]) (рис. 2).

Подробно создание схемы объекта рассмотрено в статье "Создание схемы объекта".

В схему [Отклики по рассылке] ([TestSmsResponseType]) добавьте колонку со следующими свойствами:

  • [Заголовок] ([Title]) — "Название" ("Name");
  • [Название] ([Name]) — "Name";
  • [Тип данных] ([Data type]) — "Строка 50 символов" ("Text (50 characters)").

В схему [Получатель СМС] ([TestSmsTarget]) добавьте колонки со следующими свойствами:

Табл. 1. — Основные свойства колонок схемы объекта [Получатель СМС] ([TestSmsTarget])

[Заголовок] ([Title]) [Название] ([Name]) [Тип данных] ([Data type])
Phone number PhoneNumber "Строка 50 символов" ("Text (50 characters)")
SMS text SmsText "Строка 50 символов" ("Text (50 characters)")
Contact Contact "Справочник" ("Lookup") — "Contact"
Test SMS response TestSmsResponse "Справочник" ("Lookup") — "TestSmsResponseType"

Как добавить колонку в схему объекта описано в статье "Создание схемы объекта".

Рис. 1. — Свойства и колонки схемы объекта [Получатель СМС] ([TestSmsTarget])

Рис. 2. — Свойства и колонки схемы объекта [Отклики по рассылке] ([TestSmsResponseType])

Сохраните и опубликуйте объекты.

Cоздайте справочник для объекта TestSmsResponseType и наполните его значениями "Доставлено", "Отменено", "Ошибка доставки" (“Sms delivered”, “Canceled”, “Error while receiving”) и проч. (рис. 3). Идентификаторы (Id) откликов будут использованы в коде страницы редактирования свойств условного перехода из СМС-рассылки.

Рис. 3. — Справочник [Test sms response]

2. Создание новой схемы для элемента [Переход]

Для отображения элемента в пользовательском интерфейсе [Дизайнера кампании] необходимо в пакете разработки создать новую схему модуля. Как создать схему модуля подробно описывается в статье "Создание клиентской схемы". Для созданной схемы нужно установить следующие свойства (рис. 4):

  • [Заголовок] ([Title]) — "ProcessTestSmsConditionalTransitionSchema".
  • [Название] ([Name]) — "ProcessTestSmsConditionalTransitionSchema".

ВАЖНО

Название схемы для стрелки должно начинаться с префикса “Process”

Рис. 4. — Свойства схемы модуля ProcessTestSmsConditionalTransitionSchema

В секцию [Исходный код] ([Source code]) схемы добавьте следующий исходный код:

define("ProcessTestSmsConditionalTransitionSchema", ["CampaignEnums",
    "ProcessTestSmsConditionalTransitionSchemaResources",
    "ProcessCampaignConditionalSequenceFlowSchema"],
    function(CampaignEnums) {
        Ext.define("Terrasoft.manager.ProcessTestSmsConditionalTransitionSchema", {
            extend: "Terrasoft.ProcessCampaignConditionalSequenceFlowSchema",
            alternateClassName: "Terrasoft.ProcessTestSmsConditionalTransitionSchema",
            managerItemUId: "4b5e70b0-a631-458e-ab22-856ddc913444",
            mixins: {
                parametrizedProcessSchemaElement: "Terrasoft.ParametrizedProcessSchemaElement"
            },
            // Полное имя типа связанного элемента стрелки.
            typeName: "Terrasoft.Configuration.TestSmsConditionalTransitionElement, Terrasoft.Configuration",
            // Имя элемента стрелки для привязки к элементам кампании.
            connectionUserHandleName: "TestSmsConditionalTransition",
            // Имя карточки редактирования свойств стрелки.
            editPageSchemaName: "TestSmsConditionalTransitionPropertiesPage",
            elementType: CampaignEnums.CampaignSchemaElementTypes.CONDITIONAL_TRANSITION,
            // Коллекция откликов по СМС-рассылке.
            testSmsResponseId: null,
            // Признак, который учитывает условие откликов при переводе контактов.
            isResponseBasedStart: false,
            getSerializableProperties: function() {
                var baseSerializableProperties = this.callParent(arguments);
                // Свойства для сериализации и передачи в серверную часть при сохранении.
                Ext.Array.push(baseSerializableProperties, ["testSmsResponseId", "isResponseBasedStart"]);
                return baseSerializableProperties;
            }
        });
        return Terrasoft.ProcessTestSmsConditionalTransitionSchema;
    });

Сохраните созданную схему.

3. Создание страницы редактирования свойств элемента [Переход]

Для отображения и изменения свойств элемента кампании необходимо в пакете разработки создать его страницу редактирования. Для этого нужно создать схему, расширяющую CampaignConditionalSequenceFlowPropertiesPage (пакет CampaignDesigner). Как создать замещающую схему подробно описано в статье "Создание клиентской схемы".

Для созданной схемы требуется установить следующие свойства (рис. 5):

  • [Заголовок] ([Title]) — "TestSmsConditionalTransitionPropertiesPage".
  • [Название] ([Name]) — "TestSmsConditionalTransitionPropertiesPage".
  • [Родительский объект] ([Parent object]) — "CampaignConditionalSequenceFlowPropertiesPage".

Рис. 5. — Свойства схемы страницы редактирования TestSmsConditionalTransitionPropertiesPage

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

Табл. 2. — Основные свойства локализуемых строк

[Название] ([Name]) [Значение] ([Value])
ReactionModeCaption Результат {0} шага? (What is the result of the {0} step?)
ReactionModeDefault Передача участников независимо от их ответа (Transfer participants regardless of their response)
ReactionModeWithCondition Настройка ответов для передачи участников (Set up responses for transferring participants)
IsTestSmsDelivered Тестовое сообщение доставлено (Test SMS delivered)
IsErrorWhileReceiving Ошибка при получении (Error while receiving)

В секцию [Исходный код] ([Source code]) схемы добавьте следующий исходный код:

define("TestSmsConditionalTransitionPropertiesPage", ["BusinessRuleModule"],
    function(BusinessRuleModule) {
        return {
            messages: {},
            attributes: {
                "ReactionModeEnum": {
                    dataValueType: this.Terrasoft.DataValueType.CUSTOM_OBJECT,
                    type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    value: {
                        Default: {
                            value: "0",
                            captionName: "Resources.Strings.ReactionModeDefault"
                        },
                        WithCondition: {
                            value: "1",
                            captionName: "Resources.Strings.ReactionModeWithCondition"
                        }
                    }
                },
                "ReactionMode": {
                    "dataValueType": this.Terrasoft.DataValueType.LOOKUP,
                    "type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    "isRequired": true
                },
                "IsTestSmsDelivered": {
                    "dataValueType": this.Terrasoft.DataValueType.BOOLEAN,
                    "type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                },
                "IsErrorWhileReceiving": {
                    "dataValueType": this.Terrasoft.DataValueType.BOOLEAN,
                    "type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                }
            },
 
            rules:
            {
                "ReactionConditionDecision": {
                    "BindReactionConditionDecisionRequiredToReactionMode": {
                        "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                        "property": BusinessRuleModule.enums.Property.REQUIRED,
                        "conditions": [{
                            "leftExpression": {
                                "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
                                "attribute": "ReactionMode"
                            },
                            "comparisonType": this.Terrasoft.ComparisonType.EQUAL,
                            "rightExpression": {
                                "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                "value": "1"
                            }
                        }]
                    }
                }
            },
            methods: {
                // Формирует соответствие смс-откликов (на основании справочника TestSmsResponseType).
                // Предполагается, что в системе есть справочник TestSmsResponseType
                // с записями TestSmsDelivered и ErrorWhileReceiving.
                getResponseConfig: function() {
                    return {
                        "IsTestSmsDelivered": "F2FC75B3-58C3-49A6-B2F2-353262068145",
                        "IsErrorWhileReceiving": "37B9F9D5-E897-4B7B-A65E-3B3799A18D72"
                    };
                },
 
                subscribeEvents: function() {
                    this.callParent(arguments);
                    // Привязка обработчика к событию изменения значения атрибута ReactionMode
                    this.on("change:ReactionMode", this.onReactionModeLookupChanged, this);
                },
 
                // Метод-обработчик события изменения атрибута ReactionMode.
                onReactionModeLookupChanged: function() {
                    var reactionModeEnum = this.get("ReactionModeEnum");
                    var reactionMode = this.get("ReactionMode");
                    var decisionModeEnabled = (reactionMode && reactionMode.value === reactionModeEnum.WithCondition.value);
                    if (!decisionModeEnabled) {
                        this.set("ReactionConditionDecision", null);
                    }
                },
 
                // Инициализирует свойства viewModel для отображения карточки при открытии.
                initParameters: function(element) {
                    this.callParent(arguments);
                    var isResponseBasedStart = element.isResponseBasedStart;
                    this.initReactionMode(isResponseBasedStart);
                    this.initTestSmsResponses(element.testSmsResponseId);
                },
 
                // Вспомогательный метод, обрезающий строку до указанной длины и добавляющий троеточие в конце.
                cutString: function(strValue, strLength) {
                    var ellipsis = Ext.String.ellipsis(strValue.substring(strLength), 0);
                    return strValue.substring(0, strLength) + ellipsis;
                },
 
                // Устанавливает значение статуса "СМС доставлено".
                initIsTestSmsDelivered: function(value) {
                    if (value === undefined) {
                        value = this.get("IsTestSmsDelivered");
                    }
                    this.set("IsTestSmsDelivered", value);
                },
 
                // Уустанавливает значение статуса "Ошибка при получении".
                initIsErrorWhileReceiving: function(value) {
                    if (value === undefined) {
                        var isErrorWhileReceiving = this.get("IsErrorWhileReceiving");
                        value = isErrorWhileReceiving;
                    }
                    this.set("IsErrorWhileReceiving", value);
                },
 
                // Инициализирует выбранные отклики при открытии карточки.
                initTestSmsResponses: function(responseIdsJson) {
                    if (!responseIdsJson) {
                        return;
                    }
                    var responseIds = JSON.parse(responseIdsJson);
                    var config = this.getResponseConfig();
                    Terrasoft.each(config, function(propValue, propName) {
                        if (responseIds.indexOf(propValue) > -1) {
                            this.set(propName, true);
                        }
                    }, this);
                },
 
                initReactionMode: function(value) {
                    var isDefault = !value;
                    this.setLookupValue(isDefault, "ReactionMode", "WithCondition", this);
                },
 
                // Вспомогательный метод, извлекающий массив идентификаторов из входящего JSON параметра.
                getIds: function(idsJson) {
                    if (idsJson) {
                        try {
                            var ids = JSON.parse(idsJson);
                            if (this.Ext.isArray(ids)) {
                                return ids;
                            }
                        } catch (error) {
                            return [];
                        }
                    }
                    return [];
                },
 
                onPrepareReactionModeList: function(filter, list) {
                    this.prepareList("ReactionModeEnum", list, this);
                },
 
                // Сохраняет значения откликов и настройку, добавлять условия откликов или нет.
                saveValues: function() {
                    this.callParent(arguments);
                    var element = this.get("ProcessElement");
                    var isResponseBasedStart = this.getIsReactionModeWithConditions();
                    element.isResponseBasedStart = isResponseBasedStart;
                    element.testSmsResponseId = this.getTestSmsResponseId(isResponseBasedStart);
                },
 
                // Получает сериализированые id выбранных откликов.
                getTestSmsResponseId: function(isResponseActive) {
                    var responseIds = [];
                    if (isResponseActive) {
                        var config = this.getResponseConfig();
                        Terrasoft.each(config, function(propValue, propName) {
                            var attrValue = this.get(propName);
                            if (attrValue && propValue) {
                                responseIds.push(propValue);
                            }
                        }, this);
                    }
                    return JSON.stringify(responseIds);
                },
 
                getLookupValue: function(parameterName) {
                    var value = this.get(parameterName);
                    return value ? value.value : null;
                },
 
                getContextHelpCode: function() {
                    return "CampaignConditionalSequenceFlow";
                },
 
                getIsReactionModeWithConditions: function() {
                    return this.isLookupValueEqual("ReactionMode", "1", this);
                },
 
                getSourceElement: function() {
                    var flowElement = this.get("ProcessElement");
                    if (flowElement) {
                        return flowElement.findSourceElement();
                    }
                    return null;
                },
                // Подставляет в текст название элемента, из которого выходит стрелка.
                getQuestionCaption: function() {
                    var caption = this.get("Resources.Strings.ReactionModeCaption");
                    caption = this.Ext.String.format(caption, this.getSourceElement().getCaption());
                    return caption;
                }
            },
            diff: /**SCHEMA_DIFF*/[
                // Контейнер.
                {
                    "operation": "insert",
                    "name": "ReactionContainer",
                    "propertyName": "items",
                    "parentName": "ContentContainer",
                    "className": "Terrasoft.GridLayoutEdit",
                    "values":
                    {
                        "layout":
                        {
                            "column": 0,
                            "row": 2,
                            "colSpan": 24
                        },
                        "itemType": this.Terrasoft.ViewItemType.GRID_LAYOUT,
                        "items": []
                    }
                },
                // Заголовок.
                {
                    "operation": "insert",
                    "name": "ReactionModeLabel",
                    "parentName": "ReactionContainer",
                    "propertyName": "items",
                    "values":
                    {
                        "layout":
                        {
                            "column": 0,
                            "row": 0,
                            "colSpan": 24
                        },
                        "itemType": this.Terrasoft.ViewItemType.LABEL,
                        "caption":
                        {
                            "bindTo": "getQuestionCaption"
                        },
                        "classes":
                        {
                            "labelClass": ["t-title-label-proc"]
                        }
                    }
                },
                // Список.
                {
                    "operation": "insert",
                    "name": "ReactionMode",
                    "parentName": "ReactionContainer",
                    "propertyName": "items",
                    "values":
                    {
                        "contentType": this.Terrasoft.ContentType.ENUM,
                        "controlConfig":
                        {
                            "prepareList":
                            {
                                "bindTo": "onPrepareReactionModeList"
                            }
                        },
                        "isRequired": true,
                        "layout":
                        {
                            "column": 0,
                            "row": 1,
                            "colSpan": 24
                        },
                        "labelConfig":
                        {
                            "visible": false
                        },
                        "wrapClass": ["no-caption-control"]
                    }
                },
                // Элемент списка.
                {
                    "operation": "insert",
                    "parentName": "ReactionContainer",
                    "propertyName": "items",
                    "name": "IsTestSmsDelivered",
                    "values":
                    {
                        "wrapClass": ["t-checkbox-control"],
                        "visible":
                        {
                            "bindTo": "ReactionMode",
                            "bindConfig":
                            {
                                converter: "getIsReactionModeWithConditions"
                            }
                        },
                        "caption":
                        {
                            "bindTo": "Resources.Strings.IsTestSmsDelivered"
                        },
                        "layout":
                        {
                            "column": 0,
                            "row": 2,
                            "colSpan": 22
                        }
                    }
                },
                // Элемент списка.
                {
                    "operation": "insert",
                    "parentName": "ReactionContainer",
                    "propertyName": "items",
                    "name": "IsErrorWhileReceiving",
                    "values":
                    {
                        "wrapClass": ["t-checkbox-control"],
                        "visible":
                        {
                            "bindTo": "ReactionMode",
                            "bindConfig":
                            {
                                converter: "getIsReactionModeWithConditions"
                            }
                        },
                        "caption":
                        {
                            "bindTo": "Resources.Strings.IsErrorWhileReceiving"
                        },
                        "layout":
                        {
                            "column": 0,
                            "row": 3,
                            "colSpan": 22
                        }
                    }
                }
            ]/**SCHEMA_DIFF*/
        };
    }
);

Сохраните созданную схему.

4. Создание серверной части элемента [Переход] из элемента [СМС-рассылка]

Чтобы реализовать возможность сохранения базовых и пользовательских свойств элемента кампании, для него необходимо создать класс, взаимодействующий с серверной частью приложения. Класс должен быть наследником CampaignSchemaElement и переопределять методы ApplyMetaDataValue() и WriteMetaData().

Для этого создайте схему исходного кода со следующими свойствами:

  • [Заголовок] ([Title]) — "TestSmsConditionalTransitionElement".
  • [Название] ([Name]) — "TestSmsConditionalTransitionElement".

Как создать схему исходного кода подробно описано в статье "Создание схемы [Исходный код]".

В секцию [Исходный код] ([Source code]) схемы необходимо добавить следующий исходный код:

namespace Terrasoft.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.Linq;
    using Newtonsoft.Json;
    using Terrasoft.Common;
    using Terrasoft.Core;
    using Terrasoft.Core.Campaign;
    using Terrasoft.Core.DB;
    using Terrasoft.Core.Process;
    
    [DesignModeProperty(Name = "TestSmsResponseId",
        UsageType = DesignModeUsageType.NotVisible, MetaPropertyName = TestSmsResponseIdPropertyName)]
    [DesignModeProperty(Name = "IsResponseBasedStart",
        UsageType = DesignModeUsageType.Advanced, MetaPropertyName = IsResponseBasedStartPropertyName)]
    public class TestSmsConditionalTransitionElement : ConditionalSequenceFlowElement
    {
 
        private const string TestSmsResponseIdPropertyName = "TestSmsResponseId";
        private const string IsResponseBasedStartPropertyName = "IsResponseBasedStart";
        
        public TestSmsConditionalTransitionElement() {}
        
        public TestSmsConditionalTransitionElement(TestSmsConditionalTransitionElement source)
            : this(source, null, null) {}
 
        public TestSmsConditionalTransitionElement(TestSmsConditionalTransitionElement source,
            Dictionary<Guid, Guid> dictToRebind, Core.Campaign.CampaignSchema parentSchema)
            : base(source, dictToRebind, parentSchema) {
            IsResponseBasedStart = source.IsResponseBasedStart;
            _testSmsResponseIdJson = JsonConvert.SerializeObject(source.TestSmsResponseId);
        }
 
        private string _testSmsResponseIdJson;
        
        private IEnumerable<Guid> Responses {
            get {
                return TestSmsResponseId;
            }
        }
 
        [MetaTypeProperty("{DC597899-B831-458A-A58E-FB43B1E266AC}")]
        public IEnumerable<Guid> TestSmsResponseId {
            get {
                return !string.IsNullOrWhiteSpace(_testSmsResponseIdJson)
                    ? JsonConvert.DeserializeObject<IEnumerable<Guid>>(_testSmsResponseIdJson)
                    : Enumerable.Empty<Guid>();
            }
        }
        
        [MetaTypeProperty("{3FFA4EA0-62CC-49A8-91FF-4096AEC561F6}",
    IsExtraProperty = true, IsUserProperty = true)]
        public virtual bool IsResponseBasedStart {
            get;
            set;
        }
        
        protected override void ApplyMetaDataValue(DataReader reader) {
            base.ApplyMetaDataValue(reader);
            switch (reader.CurrentName) {
                case TestSmsResponseIdPropertyName:
                    _testSmsResponseIdJson = reader.GetValue<string>();
                    break;
                case IsResponseBasedStartPropertyName:
                    IsResponseBasedStart = reader.GetBoolValue();
                    break;
                default:
                    break;
            }
        }
        
        public override void WriteMetaData(DataWriter writer) {
            base.WriteMetaData(writer);
            writer.WriteValue(IsResponseBasedStartPropertyName, IsResponseBasedStart, false);
            writer.WriteValue(TestSmsResponseIdPropertyName, _testSmsResponseIdJson, null);
        }
        
        public override object Clone() {
            return new TestSmsConditionalTransitionElement(this);
        }
        
        public override object Copy(Dictionary<Guid, Guid> dictToRebind, Core.Campaign.CampaignSchema parentSchema) {
            return new TestSmsConditionalTransitionElement(this, dictToRebind, parentSchema);
        }
        
        // Переопределяет фабричный метод по созданию исполняемого элемента
        // Возвращает элемент с типом TestSmsConditionalTransitionFlowElement
        public override ProcessFlowElement CreateProcessFlowElement(UserConnection userConnection) {
            var sourceElement = SourceRef as TestSmsElement;
            var executableElement = new TestSmsConditionalTransitionFlowElement {
                UserConnection = userConnection,
                TestSmsResponses = TestSmsResponseId,
                PhoneNumber = sourceElement.PhoneNumber,
                SmsText = sourceElement.SmsText
            };
            InitializeCampaignProcessFlowElement(executableElement);
            InitializeCampaignTransitionFlowElement(executableElement);
            InitializeConditionalTransitionFlowElement(executableElement);
            return executableElement;
        } 
    }  
}

Сохраните и опубликуйте созданную схему.

5. Создание исполняемого элемента для перехода из элемента [СМС-рассылка]

Чтобы добавить функциональность, которая выполнит учет условия откликов по отправленой смс-рассылке, создайте исполняемый элемент. Это класс, наследник класса ConditionalTransitionFlowElement.

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

  • [Заголовок] ([Title]) — "TestSmsConditionalTransitionFlowElement".
  • [Название] ([Name]) — "TestSmsConditionalTransitionFlowElement".

В секцию [Исходный код] ([Source code]) схемы необходимо добавить следующий исходный код:

namespace Terrasoft.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Terrasoft.Common;
    using Terrasoft.Core.DB;
 
    public class TestSmsConditionalTransitionFlowElement : ConditionalTransitionFlowElement
    {
 
        public string SmsText { get; set; }
 
        public string PhoneNumber { get; set; }
 
        public IEnumerable<Guid> TestSmsResponses { get; set; }
 
        private void ExtendWithResponses() {
            TransitionQuery.CheckArgumentNull("TransitionQuery");
            if (TestSmsResponses.Any()) {
                Query responseSelect = GetSelectByParticipantResponses();
                TransitionQuery.And("ContactId").In(responseSelect);
            }
        }
 
        private Query GetSelectByParticipantResponses() {
            var responseSelect = new Select(UserConnection)
                .Column("ContactId")
                .From("TestSmsTarget")
                .Where("SmsText").IsEqual(Column.Parameter(SmsText))
                    .And("PhoneNumber").IsEqual(Column.Parameter(PhoneNumber))
                    .And("TestSmsResponseId")
                        .In(Column.Parameters(TestSmsResponses)) as Select;
            responseSelect.SpecifyNoLockHints(true);
            return responseSelect;
        }
 
        protected override void CreateQuery() {
            base.CreateQuery();
            ExtendWithResponses();
        }
    }
}

Сохраните и опубликуйте созданную схему.

6. Создание замещающего модуля CampaignConnectorManager для добавления логики работы перехода

Для добавления специфической логики работы перехода при изменении источника (элемента, из которого выходит стрелка) в пакете разработки создайте новую схему модуля замещающего модуль CampaignConnectorManager. Как создать схему модуля подробно описывается в статье "Создание клиентской схемы". Для созданной схемы нужно установить следующие свойства:

  • [Заголовок] ([Title]) — "TestSmsCampaignConnectorManager".
  • [Название] ([Name]) — "TestSmsCampaignConnectorManager".

В секцию [Исходный код] ([Source code]) схемы необходимо добавить следующий исходный код:

define("TestSmsCampaignConnectorManager", [], function() {
 
    Ext.define("Terrasoft.TestSmsCampaignConnectorManager", {
        // Указываем, что замещаем модуль CampaignConnectorManager
        override: "Terrasoft.CampaignConnectorManager",
 
        // Добавляем маппинг название схема-элемента источника для стрелки - тип стрелки (full name)
        initMappingCollection: function() {
            this.callParent(arguments);
            this.connectorTypesMappingCollection.addIfNotExists("TestSmsElementSchema",
                "Terrasoft.ProcessTestSmsConditionalTransitionSchema");
        },
 
        // Виртуальный метод для перегрузки
        // Логика для процессинга стрелки перед ее подменой стрелкой с новым типом.
        additionalBeforeChange: function(prevTransition, sourceItem, targetItem) {
            // additional logic here
        },
 
        // Виртуальный метод для перегрузки
        // Заполнение специфических полей созданной стрелки на основе предыдущей стрелки.
        fillAdditionalProperties: function(prevElement, newElement) {
            if (newElement.getTypeInfo().typeName === "ProcessTestSmsConditionalTransitionSchema") {
                // Переносим настроенные отклики, если предыдущая стрелка такого же типа
                newElement.testSmsResponseId = prevElement.testSmsResponseId ? prevElement.testSmsResponseId : null;
                // Так же переносим и настройку учета откликов
                newElement.isResponseBasedStart = prevElement.isResponseBasedStart
                    ? prevElement.isResponseBasedStart
                    : false;
            }
        }
    });
});

Сохраните созданную схему.

7. Подключение замещающего модуля CampaignConnectorManager

Для подключения модуля, созданного на предыдущем шаге создайте замещающий клиентский модуль, в котором в качестве родительского объекта укажите BootstrapModulesV2 из пакета NUI. Процесс создания замещающего клиентского модуля описан в статье "Создание клиентской схемы".

В секцию [Исходный код] ([Source code]) схемы необходимо добавить следующий исходный код:

// Ставим в зависимости созданный ранее модуль TestSmsCampaignConnectorManager
define("BootstrapModulesV2", ["TestSmsCampaignConnectorManager"], function() {});

Сохраните созданную схему.

К СВЕДЕНИЮ

В реальном примере желательно создать отдельную схему объекта [СМС-рассылка]. Объекты [TestSmsElement] и [TestSmsConditionalTransitionElement] будут содержать [Id] этого объекта, а не поля SmsText, PhoneNumber… Исполняемый элемент TestSmsCampaignProcessElement в методе Execute() должен содержать логику по добавлению контактов в аудиторию рассылки. Отдельный механизм (или несколько механизмов) должны выполнить отправку рассылки, а затем зафиксировать отклики участников. На основании этих откликов и будет выполнена работа стрелки по перемещению аудитории кампании на следующий шаг.

© Terrasoft 2002-2019.

Был ли данный материал полезен?

Как можно улучшить эту статью?