Коллеги всем доброго времени суток!

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

Создал функцию:

 

(function () {
	var SysUserInRole = "SysUserInRole";
	var columns = ["Id", "SysRole.Region"];
	var store = Ext.create("Terrasoft.store.BaseStore",{
		model: SysUserInRole
	});
	var queryConfig = Ext.create("Terrasoft.QueryConfig", {
		modelName: SysUserInRole,
		columns: columns
	});
	var filters = Ext.create("Terrasoft.Filter", {
		property: "SysUser.Id",
		value: Terrasoft.CurrentUserInfo.userId
	});
	store.load({
		queryConfig: queryConfig,
		filters: filters,
		callback: function(records, operation, success) {
			try {
				debugger;
				if(success && records) {
					Terrasoft.WaUserInRoles = records;
				} else {
					window.console.info(operation);
					window.console.info(success);
					window.console.info(records);
				}
			} catch(ex) {
				Terrasoft.Mask.hide({force: true});
				Terrasoft.Logger.error(ex, Terrasoft.LogDestination.Console);
				window.console.error(ex);
				return;
			}
		},
		scope: this
	});
}());

Добавил ее в манифест в блок:

 

{
	"ApplicationRequiredModels": [
		"SysAdminUnit",
		"SysUserInRole"
	],
	"CustomSchemas": [
		....
		"WaMobileGetCurrentUserRoles"
	],
}

При выполнении не может определить lockupModel:

 

var lookupModel = Ext.ClassManager.get(columnConfig.modelName);

http://prntscr.com/o3ctl3

 

В чем может быть проблема? Заранее благодарен.

Нравится

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

Добрый день!

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

В зависимости от значения в справочном поле могут сильно отличаться дополнительные обязательные для заполнения параметры. 

Так что думал решить этот момент за счет автогенерируемой страницы.

Один нюанс - логика должна отрабатывать до сохранения записи в разделе.

Нравится

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

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

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

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

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

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

Коллеги, приветствую!

Есть ли возможность отправлять на визирование разным сотрудникам в зависимости от условия? Например, если отправить заявку начальнику, но если начальник в отпуске, то его заместителю.

Благодарю заранее.

Нравится

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

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

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

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

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

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

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

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

Как получить ID справочного значения в JS зная только название для того что бы потом установить его в выпадающем списке справочника?

Нравится

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

Коваленко Илья,

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "Contact"
});
esq.addColumn('Id');
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 'Name', name));
esq.getEntityCollection(function(response)
{
	if(response.success)
	{
		var entities = response.collection.getItems();
		Terrasoft.each(entities, function(item){
			var id = item.get('Id');
		});
	}
});

 

Добрый день!

Без дополнительного запроса в базу для получения id справочника по названию (например) не получится сделать.

Если справочник не планируется изменять, то значения справочника лучше вынести в константы.

Сидоров Александр В., Можете показать пример такого запроса?

Коваленко Илья,

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "Contact"
});
esq.addColumn('Id');
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 'Name', name));
esq.getEntityCollection(function(response)
{
	if(response.success)
	{
		var entities = response.collection.getItems();
		Terrasoft.each(entities, function(item){
			var id = item.get('Id');
		});
	}
});

 

Сидоров Александр В.,

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

esq.rowCount = 1

 

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

Согласен. Но справочник может быть не уникален по имени. Поэтому и привел пример со списком, где надо делать постобработку

Сидоров Александр В.,

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

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

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

Нравится

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

К сожалению, возможность создавать деталь с редактируемым реестром с помощью мастера отсутствует.

Подробнее о создании такой детали через конфигурацию можно почитать в статье.

К сожалению, возможность создавать деталь с редактируемым реестром с помощью мастера отсутствует.

Подробнее о создании такой детали через конфигурацию можно почитать в статье.

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

Доброго времени суток! Подскажите, пожалуйста, как добавить CheckBox в средства связи. Для средства связи добавил в объекте логическое значение, например с названием "UsrIsMain".

Нравится

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

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

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

Григорий Чех,

В принципе мне понятно, как конфиг строится. Добавлял TextEdit поле, Lookup поле. А вот CheckBox не получается, выбрасывает ошибку следующую:

 

message: Cannot read property 'changeEvent' of undefined 

 date: Thu Jun 13 2019 11:01:45 GMT+0300 (Москва, стандартное время)

moduleId: CardModuleV2_########GUID###########_ContactPageV2_detail_ContactCommunication

moduleName: DetailModuleV2



Строил сам CheckBox вот так:

{

                        className: "Terrasoft.CheckBoxEdit",

                        id: "CheckBoxEditId",

                        classes: {

                            wrapClass: ["communication-detail-edit-user-class", "communication-additional-edit-label-wrap"]

                        },

                        value: {

                            bindTo: "UsrIsMain"

                        },

                        change: {

                            bindTo: "changeIsMainFlag"

                        }

  };



Сама функция changeIsMainFlag объявлена в ViewConfig'е.

 

Григорий Чех,

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

В детали средств связи контакта в пакете MarketingCampaign есть такое поле «Не актуальный» (NonActual) у каждого средства связи. Посмотреть на реализацию можно в схеме ContactCommunicationDetail.

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

Имеется иерархическая деталь с редактируемым реестром. В ней возникает проблема при сохранении дробного числа. Появляется ошибка Cannot read property 'getAttribute' of null, которая возникает в результате того, что метод GetDomRow возвращает undefined. После этого я не могу больше сохранять дробные числа в реестре и приходится перезагружать страницу. Первое сохранение проходит удачно, хоть и успевает появиться ошибка. В результате чего возникает такая проблема? ниже представлен код детали

define("IDSBRefrigeratorInTMADetail",
    ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities", "ServiceHelper"],
    function (ConfigurationGrid, ConfigurationGridGenerator, ConfigurationGridUtilities, ServiceHelper) {
        return {
            messages: {
                "ReloadRefrigeratorsInTMAGrid": {
                    "mode": Terrasoft.MessageMode.BROADCAST,
                    "direction": Terrasoft.MessageDirectionType.SUBSCRIBE
                }
            },
            entitySchemaName: "IDSBRefrigeratorInTMA",
            attributes: {
                "IsEditable": {
                    dataValueType: Terrasoft.DataValueType.BOOLEAN,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    value: true
                }
            },
            mixins: {
                ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
            },
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "DataGrid",
                    "values": {
                        "hierarchical": true,
                        "hierarchicalColumnName": "IDSBParent",
                        "className": "Terrasoft.ConfigurationGrid",
                        "generator": "ConfigurationGridGenerator.generatePartial",
                        "generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
                        "changeRow": { "bindTo": "changeRow" },
                        "unSelectRow": { "bindTo": "unSelectRow" },
                        "onGridClick": { "bindTo": "onGridClick" },
                        "activeRowAction": { "bindTo": "onActiveRowAction" },
                        "initActiveRowKeyMap": { "bindTo": "initActiveRowKeyMap" },
                        "multiSelect": false
                    }
                },
                {
                    "operation": "remove",
                    "name": "AddRecordButton"
                }]/**SCHEMA_DIFF*/,
            methods: {
                generateActiveRowControlsConfig: function (id, columnsConfig, rowConfig) {
                    this.columnsConfig = columnsConfig;
                    var gridData = this.getGridData();
                    var activeRow = gridData.get(id);
                    var isEditableColumn;
                    if (activeRow.values.IDSBParent === "") {
                        isEditableColumn = this.ParentColumnIsEditable;
                    }
                    else {
                        isEditableColumn = this.ColumnIsEditable;
                    }
                    var gridLayoutItems = [];
                    var currentColumnIndex = 0;
                    Terrasoft.each(columnsConfig, function (columnConfig) {
                        var cellConfig = this.getActiveRowCellConfig(columnConfig, currentColumnIndex);
                        cellConfig.enabled = isEditableColumn(cellConfig.name);
                        if (!cellConfig.hasOwnProperty("isNotFound")) {
                            gridLayoutItems.push(cellConfig);
                        }
                        currentColumnIndex += cellConfig.layout.colSpan;
                    }, this);
                    this.applyBusinessRulesForActiveRow(id, gridLayoutItems);
                    var viewGenerator = Ext.create(this.getRowViewGeneratorClassName());
                    viewGenerator.viewModelClass = this;
                    var gridLayoutConfig = viewGenerator.generateGridLayout({
                        name: this.name,
                        items: gridLayoutItems
                    });
                    rowConfig.push(gridLayoutConfig);
                },
                ParentColumnIsEditable: function (columnName) {
                    return (columnName === "IDSBPlacementPrice" || columnName === "IDSBNumberOfDoors" || columnName === "IDSBProlongation");
                },
                ColumnIsEditable: function (columnName) {
                    return (columnName === "IDSBRBBottlePlan" || columnName === "IDSBRBBottleCurrent"
                        || columnName === "IDSBBRBottlePlan" || columnName === "IDSBBRBottleCurrent");
                },
                init: function () {
                    this.callParent(arguments);
                    this.set("IsPageable", false);
                    this.set("RowCount", 28000);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },
                onReloadRefrigeratorsInTMAGrid: function (args) {
                    var id = this.get("MasterRecordId");
                    debugger;
                    if (id === args) {
                        this.reloadGridData();
                    }
                },
                addGridDataColumns: function (esq) {
                    this.callParent(arguments);
                    if (!esq.columns.contains("IDSBParent")) {
                        esq.addColumn("IDSBParent");
                    }
                },
                getGridDataColumns: function () {
                    var gridDataColumns = this.callParent(arguments);
                    if (!gridDataColumns.IDSBParent) {
                        gridDataColumns.IDSBParent = {
                            path: "IDSBParent"
                        };
                    }
                    return gridDataColumns;
                },
                addToolsButtonMenuItems: function (toolsButtonMenu) {
                    this.addGridOperationsMenuItems(toolsButtonMenu);
                    if (this.useDetailWizard) {
                        this.addDetailWizardMenuItems(toolsButtonMenu);
                    }
                },
                prepareResponseCollection: function (collection) {
                    collection.each(function (item) {
                        var parent = item.get("IDSBParent");
                        var parentId = parent && parent.value;
                        if (parentId) {
                            item.set("IDSBParentId", parentId);
                        }
                        Terrasoft.each(item.columns, function (column) {
                            this.addColumnLink(item, column);
                            this.applyColumnDefaults(column);
                        }, this);
                    }, this);
                }
            }
        };
    });

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

Нравится

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

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

В любом случае вам может помочь только отладка кода!

решил задачу тупо влоб, переопределив метод сохранения. Написал своё сохранение, вызывая сервис из сервера. немного медленно, но работает

saveRowChanges: function (row, callback, scope) {
                    scope = scope || this;
                    callback = callback || Terrasoft.emptyFn;
                    if (row && this.getIsRowChanged(row)) {
                        if (row.values.IDSBParent !== "") {
                            this.saveChildRow(row, callback, scope);
                        }
                        else {
                            this.saveParentRow(rowm, callback, scope);
                        }
                    } else {
                        callback.call(scope);
                    }
                },
saveChildRow: function (row, callback, scope) {
                    var changed = row.changedValues;
                    debugger;
                    if (!changed.hasOwnProperty("IDSBBRBottleCurrent")) {
                        changed.IDSBBRBottleCurrent = row.values.IDSBBRBottleCurrent;
                    }
                    if (!changed.hasOwnProperty("IDSBBRBottlePlan")) {
                        changed.IDSBBRBottlePlan = row.values.IDSBBRBottlePlan;
                    }
                    if (!changed.hasOwnProperty("IDSBRBBottlePlan")) {
                        changed.IDSBRBBottlePlan = row.values.IDSBRBBottlePlan;
                    }
                    if (!changed.hasOwnProperty("IDSBRBBottleCurrent")) {
                        changed.IDSBRBBottleCurrent = row.values.IDSBRBBottleCurrent;
                    }
                    callback = this.reloadGridData;
                    var serviceSaveData = {
                        RowId: row.values.Id,
                        bottles: changed
                    }
                    ServiceHelper.callService("IDSBPlacingREService", "SaveChildRow",
                        callback, serviceSaveData, scope);
                }

 

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

Здравствуйте, выполняю вот такое задание:

Реализовать следующую логику: 

при добавлении новой записи 

«Задолженности» должна производиться выборка всех договоров данного должника, 

суммирование значений полей «Общая сумма задолженности», 

«Основной долг», «Штрафы», 

«Проценты и комиссии» данных записей объекта 

«Договоры» и запись в соответствующие поля текущей записи объекта «Задолженности». 

Реализуется с помощью бизнес процесса, который запускается по событию «Добавление записи» текущего объекта

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

 

Нравится

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

Действительно, как подсказал выше Александр  используя в элементе чтения данных параметр [СЧИТАТЬ ФУНКЦИЮ] = Сумма, а потом элемент Измtнить данные позволяет избежать кодирования :)

Добрый день!

Данные из коллекции нужно считывать так:

var entities = Get<ICompositeObjectList<ICompositeObject>>("ReadDataUserTask1.ResultCompositeObjectList");

Т.е. в вашем случае код будет таким:

var entities = Get&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt;("ReadDataUserTask1.ResultCompositeObjectList");
 
var result = 0;
 
foreach(var entity in entities) 
{
    	var sum = 0d;
    	if (entity.TryGetValue&lt;double&gt;("Sum", out sum))
    	{
    		result += sum;  
    	}
}

 

Сидоров Александр В.,

Т.е. мне надо использовать задание-сценарий? А как потом из него получить это значение для записи? Или мне все в одном сценарии можно выполнить?

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

Действительно, как подсказал выше Александр  используя в элементе чтения данных параметр [СЧИТАТЬ ФУНКЦИЮ] = Сумма, а потом элемент Измtнить данные позволяет избежать кодирования :)

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

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

Добрый день, коллеги.

Сейчас, при создании заявки, автоматически создается печатная форма. Но нужно, чтобы возможность скачать печатную форму появлялась не при создании заявки, а чуть позже, при срабатывании какого-либо другого события. Подскажите пожалуйста, каким образом лучше всего реализовать вышеописанную задачу?

Заранее благодарю :)

Нравится

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

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

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

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

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



Как такое можно реализовать?

Нравится

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

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

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

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

Да, спасибо большое! Очень похоже на то, что мне нужно. Я создал событие которое мне нужно, далее с помощью системного элемента "читать данные" взял последнюю измененную запись. Теперь нужно ее отправить. Не могли бы вы подсказать как это сделать?

Попробовал данный код, чтобы считать и отправить данные, но запрос не доходит(



EntityCollection entities = Get<EntityCollection>("DataReader.ResultEntityCollection");

string json = JsonConvert.SerializeObject(entities);

string authServiceUri = "http://123/BPMTEST/test.php";

var authRequest = System.Net.HttpWebRequest.Create(authServiceUri) as System.Net.HttpWebRequest;

authRequest.Method = "POST";

authRequest.ContentType = "application/json";

using (var requestStream = authRequest.GetRequestStream())

{

    using (var writer = new System.IO.StreamWriter(requestStream))

    {

        writer.Write(json);

    }

}

return true;

Добрый день!

Попробуйте использовать элемент БП "Вызов веб-сервиса". Пример тут

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