Вопрос

Здравствуйте, уважаемое сообщество!

В базе имеется много Контрагентов внесённых вручную, сделали интеграцию Контрагентов из 1С при помощи 1С Коннектора, естественно появились дубли

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

Вопрос, как повлиять на то какой объект оставить в системе во время объединения дублей, а какой удалить?

Проверяю следующим запросом к базе:

select * from Account where name = 'Высший Вкус ООО (ВВ)';
select * from SmrSyncHistory where localid in (select id from Account where name = 'Высший Вкус ООО (ВВ)');

 

До объединения:

 

После объединения:

 

У меня такой же вопрос

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

Пока в стандартном механизме платформы нет выбора золотой записи.
В случае использования 1C Connector вы можете сразу настроить признак [Использовать для дедупликации] по полю Название, чтобы дубли вообще не создавались. Подробнее -https://samarasoft.com/docs/1c-connector/integration-setting-bpmonline/fields-mapping/

В стандартном механизме в качестве золотой берётся первое значение в коллекции. В схеме DeduplicationMergeHandler функция MergeEntityDublicates начинается так:

public void MergeEntityDublicates(string schemaName, int groupId, List<Guid> duplicateRecordIds, Dictionary<string, string> resolvedConflicts) {
	EntitySchema entitySchema = _userConnection.EntitySchemaManager.GetInstanceByName(schemaName);
	EntityCollection duplicates = GetEntityDublicates(schemaName, duplicateRecordIds);
	Entity goldenEntity = duplicates.FirstOrDefault();
	if (goldenEntity == null) {
		return;
	}
	duplicates.RemoveFirst();
	duplicateRecordIds.Remove(goldenEntity.PrimaryColumnValue);
	if (duplicates.Count == 0) {
		return;
	}

А коллекция отсортирована по дате создания, старые вначале:

public EntityCollection GetEntityDublicates(string schemaName, List<Guid> ids, List<string> columns = null) {
	EntitySchema schema = _userConnection.EntitySchemaManager
		.GetInstanceByName(schemaName);
	var esq = new EntitySchemaQuery(schema);
	if (columns == null) {
		esq.AddAllSchemaColumns();
	} else {
		esq.PrimaryQueryColumn.IsAlwaysSelect = true;
		if (!columns.Contains("CreatedOn")) {
			esq.AddColumn("CreatedOn");
		}
		foreach (string columnName in columns) {
			esq.AddColumn(columnName);
		}
	}
	esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal,
		esq.RootSchema.PrimaryColumn.Name, ids.Cast<object>()));
	EntityCollection entityCollection = esq.GetEntityCollection(_userConnection);
	entityCollection.Order("CreatedOn", OrderDirection.Ascending);
	return entityCollection;
}

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

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

Спасибо за советы, только сейчас пролучилось вернуться к этому кейсу

Я так понимаю что включать признак дедупликации в Коннекторе уже поздно, ну или чистить записи и проводить интеграцию заново

Хочу попробовать сделать по совету Зверева Александра, но не могу найти статью или ответы на комьюнити как правильно замещать "Исходный код", я так понял надо просто поменять Ascending на Descending.

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

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

ОМАЙГАДБЛ... всё гениальное просто, спасибо, попробую ))))))))

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

Создал иерархическую деталь с редактируемым реестром. Но появилась проблема при количестве дочерних элементов больше 8. Они почему не отображаются, выдается ошибка Cannot read property 'getAttribute' of null. В БД всё верно. 

Вот код детали

define("IDSBRefrigeratorInTMADetail",
    ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
    function () {
        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",
                        "maxColumns": 48,
                        "maxRowsCount": 10000,
                        "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.isEditableParentColumn;
                    }
                    else {
                        isEditableColumn = this.isEditableColumn;
                    }
                    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);
                },
                isEditableParentColumn: function (columnName) {
                    return false;
                },
                isEditableColumn: function (columnName) {
                    return (columnName === "IDSBBottlePlan");
                }/*,
                init: function () {
                    this.callParent(arguments);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },
                onReloadRefrigeratorsInTMAGrid: function (args) {
                    this.reloadGridData();
                }*/
            }
	};
});

 

У меня такой же вопрос

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

Для упрощения отладки посмотрите SQL профайлером запросы которые отправляются в БД.

Григорий Чех, думаете нужно заместить метод addGridDataColumns?

Григорий имел в виду использование профайлера. Естественно, только для случаев, когда есть доступ к серверу БД.

посмотрел профайлер. Выполняется следующий запрос. Забил его сам в SQL Management. Выдал недостающие элементы, которые как раз невыведены на экран. Ошибка возникает когда нажимаю "Показать больше"

SELECT
	[IDSBRefrigeratorInTMA].[Id] [Id],
	[IDSBRefrigeratorInTMA].[IDSBStreet] [IDSBStreet],
	[IDSBRefrigeratorInTMA].[IDSBCustomerInTMAId] [IDSBCustomerInTMAId],
	[IDSBRefrigeratorInTMA].[ITTradeMarketId] [ITTradeMarketId],
	[ITTradeMarket].[ITName] [ITTradeMarket.ITName],
	[IDSBRefrigeratorInTMA].[MonthId] [MonthId],
	[Month].[Name] [Month.Name],
	[IDSBRefrigeratorInTMA].[IDSBBottlePlan] [IDSBBottlePlan],
	[IDSBRefrigeratorInTMA].[IDSBParentId] [IDSBParentId],
	[IDSBParent].[IDSBStreet] [IDSBParent.IDSBStreet],
	[ITTradeMarket].[ITTypeId] [ITTradeMarket.ITTypeId],
	[ITType].[Name] [ITType.Name],
	(
SELECT
	COUNT([SubEntryPoint].[Id]) [Count]
FROM
	[dbo].[EntryPoint] [SubEntryPoint] WITH(NOLOCK)
WHERE
	[SubEntryPoint].[EntityId] = [IDSBRefrigeratorInTMA].[Id]
	AND [SubEntryPoint].[IsActive] = 1) [SubEntryPoint],
	[IDSBRefrigeratorInTMA].[CreatedOn] [CreatedOn],
	[IDSBRefrigeratorInTMA].[CreatedById] [CreatedById],
	[CreatedBy].[Name] [CreatedBy.Name],
	[CreatedBy].[PhotoId] [CreatedBy.PhotoId],
	[IDSBRefrigeratorInTMA].[ModifiedOn] [ModifiedOn],
	[IDSBRefrigeratorInTMA].[ModifiedById] [ModifiedById],
	[ModifiedBy].[Name] [ModifiedBy.Name],
	[ModifiedBy].[PhotoId] [ModifiedBy.PhotoId],
	[IDSBRefrigeratorInTMA].[ProcessListeners] [ProcessListeners]
FROM
	[dbo].[IDSBRefrigeratorInTMA] [IDSBRefrigeratorInTMA] WITH(NOLOCK)
	LEFT OUTER JOIN [dbo].[ITTradeMarket] [ITTradeMarket] WITH(NOLOCK) ON ([ITTradeMarket].[Id] = [IDSBRefrigeratorInTMA].[ITTradeMarketId])
	LEFT OUTER JOIN [dbo].[Month] [Month] WITH(NOLOCK) ON ([Month].[Id] = [IDSBRefrigeratorInTMA].[MonthId])
	LEFT OUTER JOIN [dbo].[IDSBRefrigeratorInTMA] [IDSBParent] WITH(NOLOCK) ON ([IDSBParent].[Id] = [IDSBRefrigeratorInTMA].[IDSBParentId])
	LEFT OUTER JOIN [dbo].[ITITTradeMarketType1] [ITType] WITH(NOLOCK) ON ([ITType].[Id] = [ITTradeMarket].[ITTypeId])
	LEFT OUTER JOIN [dbo].[Contact] [CreatedBy] WITH(NOLOCK) ON ([CreatedBy].[Id] = [IDSBRefrigeratorInTMA].[CreatedById])
	LEFT OUTER JOIN [dbo].[Contact] [ModifiedBy] WITH(NOLOCK) ON ([ModifiedBy].[Id] = [IDSBRefrigeratorInTMA].[ModifiedById])
WHERE
	[IDSBRefrigeratorInTMA].[ITTradeMarketId] = '54368FDE-6D00-4BDE-BAAE-EDEA56EBAA33'
ORDER BY
	[Id] ASC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

 

Может, 8 элементов видно как раз из-за выборки порциями по 10? Судя по окончанию SQL-запроса, это как раз вторая десятка, первая пропущена.

А где именно вылетает «Cannot read property 'getAttribute' of null», полный стек не видно?

Вылетает на этом методе. В строке var n = this.getDomRow(i) в n кладется undefined и далее соответственно вылетает ошибка. В i в этот момент родительская колонка

onCollectionDataLoaded: function(e, t, a) {
        if (this.theoreticallyActiveRows = null,
        !this.rows.length)
            return this.collection = this.collection || e,
            this.prepareCollectionData(),
            void this.safeRerender();
        if (!Ext.Object.isEmpty(t) && this.rendered) {
            var r = []
              , s = {
                rows: r
            };
            if (t.each(function(e) {
                this.prepareCollectionItem(e);
                var t = this.getRow(e);
                r.push(t),
                a && ("top" !== a.mode ? this.rows.push(t) : this.rows.splice(0, 0, t))
            }, this),
            this.hierarchical && !t.isEmpty()) {
                var i = t.getByIndex(0).get(this.hierarchicalColumnName);
                if (s[this.hierarchicalColumnName] = i,
                "listed" === this.type && i) {
                    var n = this.getDomRow(i)
                      , o = parseInt(n.getAttribute("level"), 10);
                    s.rowLevel = o + 1
                }
            }
            var l = [];
            this.renderGrid(l, s);
            for (var c = "", h = 0, u = l.length; h < u; h += 1)
                c += Ext.DomHelper.createHtml(l[h]);
            Ext.Object.isEmpty(a) && (a = {
                mode: "bottom"
            }),
            this.addRows(c, a),
            this.checkNeedLoadData()
        }
    },

 

Что-то не могу найти такой функции в «коробке».

А иерархичность и редактируемость сами по себе совместимы? На других таких деталях ограничения в 8 нет?

Если убираю редактируемость, ошибка не исчезает. Если убираю иерархичность, всё отображается нормально

Это логично, если сбой при превышении 8 потомков. В плоской детали никаких потомков нет. Сравните с другими иерархическими деталями, есть там такое ограничение или нет?

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

init: function () {
                    this.callParent(arguments);
                    this.set("IsPageable", false);
                    this.set("RowCount", 28000);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },

 

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

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

Пытаюсь обновить запись из внешнего приложения через сабж (0/dataservice/json/reply/UpdateQuery).

Формирую JSON

{
  "rootSchemaName": "UsrPrintTemplates",
  "operationType": 2,
  "filters": {
    "RootSchemaName": "UsrPrintTemplates",
    "logicalOperation": 0,
    "isEnabled": true,
    "filterType": 1,
    "ComparisonType": 3,
    "leftExpression": {
      "expressionType": 0,
      "columnPath": "UsrBitrixId"
    },
    "rightExpression": {
      "expressionType": 2,
      "parameter": {
        "dataValueType": 4,
        "value": 2098527
      }
    }
  },
  "columnValues": {
    "items": {
      "Name": {
        "expressionType": 2,
        "parameter": {
          "dataValueType": 1,
          "value": "Акт"
        }
      },
      "UsrFileType": {
        "expressionType": 2,
        "parameter": {
          "dataValueType": 0,
          "value": "dce4c8c1-4784-475e-8fac-7c244053095c"
        }
      }
    }
  },
  "isForceUpdate": false
}

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

но у меня почему-то обновляются все записи в таблице, т.е. фильтр не отрабатывает.

Как мне его записать, чтобы обновилась 1 запись, в которой поле UsrBitrixId = 2098527 ?

У меня такой же вопрос

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

Если есть доступ к базе, посмотрите в SQL-профайлере, что за запрос получается, с каким фильтром. Возможно, дело в неверно указанном типе для колонки UsrBitrixId.

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

Здравствуйте! Нужно добавить одна текстовое поля на странице генерация отчета.

Задача состоит в добавление фильтраций по текстовое значение, но когда я пробовал добавить новое поле, оно не появляется. Я попробовал добавить: "Text", "SHORT_TEXT", "LONG_TEXT", все из данный link: https://academy.terrasoft.ru/api/jscoreapi/7.12.0/#!/api/Terrasoft.core…, добавляются только "INTEGER","LOOKUP","ENUM", и "DATE". Как я могу добавить это поле что бы оно было видно? Может для этого поле мне нужно указать другие параметры.

P.S: Отчет создан через "BPMonlineReportDesigner"

Прикрепленные файлы
Code.png28.65 КБ
Fields.png6.38 КБ

У меня такой же вопрос

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

Добрый день!
1) Проверьте, что в локализируемых строках есть строка "Name".
2) Попробуйте тип "TEXT" (заглавными буквами).
3) Что VBName - есть такая колонка.
4) Может есть ошибки в консоли. И они могут подсказать вам

Добрый день Александр, я проверил все эти пункты, все колонки есть и локализированная строка тоже есть.  Сделал debugg, и нашёл что он использует модуль ReportFilterModule, и в коде, в switch  нет такой тип TEXT, но когда я пробовал замещать, вышло ошибка, что запрещено замещение модулей.  Может подсказать если есть другие способы, что бы добавить там это поле

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

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

У меня такой же вопрос

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

Добрый день!
Если не нужно при этом генерировать сигналы объектов, то посоветую реализовать все в хранимой процедуре. Там уже реализовать цикл. Тем самым вы добьетесь максимальной производительности. А процедуру вызывать в скрипте C#.

Если доступа к серверу нет, то можно и без хранимок, используя в C#-скрипте БП классы Select и Update. С ними тоже сигналы не генерируются. А если нужно, чтобы по каждой записи отрабатывала логика встроенных и отдельных БП на изменение ответственного, то только с использованием класса EntitySchemaQuery.

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

Да забыл уточнить доступа к серверу действительно нет.

 

Пробовал реализовать через esq: 

          var isOwnerInChange = true;
           while (isOwnerInChange) {
                var subQuery = new EntitySchemaQuery(_uc.EntitySchemaManager,"UsrChangeOwnerHelperLog");
                    subQuery.AddColumn("UsrEntityId");
    
                var entitySchemaManager = _uc.EntitySchemaManager;
                var esq = new EntitySchemaQuery(entitySchemaManager, "Название схемы");
                esq.UseAdminRights = false;
                esq.AddAllSchemaColumns();

              //  какие то фильтры
                
                var mainFilter = new EntitySchemaQueryFilter(FilterComparisonType.NotExists);
                    mainFilter.LeftExpression = esq.CreateSchemaColumnExpression("Id");
                    mainFilter.RightExpressions.Add(new EntitySchemaQueryExpression(subQuery));
                    esq.Filters.Add(mainFilter);
                
                esq.RowCount=1000;
                    
                var entities = esq.GetEntityCollection(_uc);
                
                if (entities.Count > 0)
                    {
                        foreach (Entity entity in entities)
                        {
                            var entityId = entity.GetTypedColumnValue<Guid>("Id");
                            var newOwnerId = SearchOwner(accountId, "Account");

                            //Какая то логика
                        }
                } else {
                    isOwnerInChange = false;
                }
            }

В конце не забудьте каждой entity.Save();

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

Как заместить функцию initconfig модуля UserCasesListModule.

Для изменения фильтрации нужно изменить данную функцию у этого модуля.

Подскажите как это правильно сделать?

Пробывал сделать вот так результатов не дало

define("ITUserCasesListModule", ["terrasoft", "UserCasesListModule","ext-base", "UserCasesListModuleResources",
"PortalClientConstants",
		"BaseNestedModule", "GridUtilitiesV2", "ContainerListGenerator", "ContainerList", "DashboardGridModule",
		"css!PortalModulesCSS"],
	function(Terrasoft, Ext, resources, PortalClientConstants) {
 
		Ext.define("Terrasoft.configuration.ITUserCasesListModule", {
			extend: "Terrasoft.UserCasesListModule",
			alternateClassName: "Terrasoft.ITUserCasesListModule",
 
			Ext: null,
			sandbox: null,
			Terrasoft: null,
			showMask: null,
 
			/**
			 * ### ###### ###### ############# ### ########## ######.
			 * @type {String}
			 */
			viewModelClassName: "Terrasoft.UserCasesListViewModel",
 
			/**
			 * ### ##### ########## ############ ############# ########## ######.
			 * @type {String}
			 */
			viewConfigClassName: "Terrasoft.UserCasesListViewConfig",
 
			/**
			 * ### ##### ########## #############.
			 * @type {String}
			 */
			viewGeneratorClass: "Terrasoft.ViewGenerator",
 
			/**
			 * ############## ###### ############ ######.
			 * @protected
			 * @overridden
			 */
			initConfig: function() {
				this.moduleConfig =	{
					"caption": "",
					"sectionId": PortalClientConstants.SysModule.PortalMainPageSectionId,
					"entitySchemaName": "Case",
					"filterData": "{\"className\":\"Terrasoft.FilterGroup\",\"items\":{},\"logicalOperation\":0," +
						"\"isEnabled\":true,\"filterType\":6,\"rootSchemaName\":\"Case\",\"key\":\"\"}",
					"style": "widget-green",
					"orderDirection": 2,
					"orderColumn": "RegisteredOn",
					"rowCount": 10,
					"gridConfig": {
						"items": [
							{
								"bindTo": "Number",
								"type": "text",
								"position": {
									"column": 0,
									"colSpan": 6,
									"row": 1
								},
								"aggregationType": "",
								"metaPath": "Number",
								"path": "Number"
							},
 
							{
								"bindTo": "RegisteredOn",
								"type": "title",
								"position": {
									"column": 50,
									"colSpan": 0,
									"row": 1
								},
								"orderDirection": 2,
								"orderPosition": 1,
								"dataValueType": 7,
								"aggregationType": "",
								"metaPath": "RegisteredOn",
								"path": "RegisteredOn"
							}
						]
					}
				};
			}
 
		});
 
		return Terrasoft.ITUserCasesListModule;
	}
);

 

У меня такой же вопрос

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

Выходит во такая ошибка

Казанцев Андрей Юрьевич,

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

Теперь по Вашему вопросу - ошибка в заголовке функции. Должно быть вот так:

define("ITUserCasesListModule", ["terrasoft", "ext-base", "UserCasesListModuleResources",
"PortalClientConstants",
		"BaseNestedModule", "GridUtilitiesV2", "ContainerListGenerator", "ContainerList", "DashboardGridModule",
		"css!PortalModulesCSS", "UserCasesListModule"],
	function(Terrasoft, Ext, resources, PortalClientConstants) {

 

Алла Савельева пишет:

Казанцев Андрей Юрьевич,

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

Теперь по Вашему вопросу - ошибка в заголовке функции. Должно быть вот так:


 
define("ITUserCasesListModule", ["terrasoft", "ext-base", "UserCasesListModuleResources",
"PortalClientConstants",
		"BaseNestedModule", "GridUtilitiesV2", "ContainerListGenerator", "ContainerList", "DashboardGridModule",
		"css!PortalModulesCSS", "UserCasesListModule"],
	function(Terrasoft, Ext, resources, PortalClientConstants) {

Как это можно обойти?

 

Обратите внимание, у Аллы приведен другой порядок в define.

Казанцев Андрей Юрьевич пишет:
Как это можно обойти?

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

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

Добрый день !

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

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

У меня такой же вопрос

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

Добрый день!
Выполнять в бизнес процессе, который по вашему расписанию будет отсылать Email сообщение (пример).
А вот сформировать тело сообщения с таблицей без программирования уже сложно.

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

Спасибо. Сложно= невозможно, я правильно понимаю ? А если исключить таблицу, и представить просто список ?

LilyG,

Ну да. Считать список можно стандартными блоками БП. А вот из списка сформировать текст, который потом пойдет в сообщение - уже нужен блок "Задание сценарий", а это уже программирование

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

Добрый день.

Подскажите как реализовать фильтрацию по колонке Status по определенным статусам обращений(не отображались закрытые и отмененные обращения)?

У меня такой же вопрос

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

См. аналогичное добавление фильтра здесь.

Зверев Александр пишет:

См. аналогичное добавление фильтра здесь.

Этот вариант не рабочий. Потому что при добавлении функции она не вызывается. Нашел другое решение, все работает. 

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

Добрый день!

Пытаюсь найти метод, назначающий права доступа на карточку контрагента. Просмотрел обработку нажатия кнопки Действия-Настроить права доступа. В схеме BasePageV2 нашел обработчик кнопки:

actionMenuItems.addItem(this.getButtonMenuItem({
                    "Caption": {"bindTo": "Resources.Strings.EditRightsCaption"},
                    "Tag": "editRights",
                    "Visible": {"bindTo": "getSchemaAdministratedByRecords"}
                }));

метод же найти не могу.

Нужно для назначения прав на страницу контрагента в БП без использования Terrasoft.Core.DB

У меня такой же вопрос

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

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

В БП в элементе 'Задание-сценарий' можно реализовать произвольный запрос, в котором выполнять добавление/изменение/удаление данных напрямую в базу данных без использования Terrasoft.Core.DB:

var customQuery = new CustomQuery(context.UserConnection);
customQuery.SqlText = @"insert into Cases (Id) values (newid())";
using (DBExecutor dbExecutor = context.UserConnection.EnsureDBConnection())
{
	var datareader = customQuery.ExecuteReader(dbExecutor);
}
return true;

Вот ещё другой пример:

var userConnection = context.UserConnection;
var dr = new CustomQuery(userConnection, String.Format(
"update case set SolutionProvidedOn = null where Id = 974ca9fc-c066-4a7a-ac65-7ec91a44a067")).ExecuteReader(dbExecutor);
return true;

 

Спасибо, Алла.

В БП этот код вызывает ошибку компиляции "The name dbExecutor does not exist in the current context"

Либо "The type or namespace name 'IDataReader' coul not be found" в первом варианте.

То есть это работает только для неинтерпетируемого процесса? 

Естественно, использование в БП блоков скриптов на C# требует компиляции процесса.

Виталий Егоров,

Если Вы используете второй вариант, попробуйте вместо UserConnection написать context.UserConnection.

 

Если первый вариант, то приблизительно такой код:

var userConnection = context.UserConnection;
var customQuery = new CustomQuery(userConnection);
customQuery.SqlText = @"insert into Cases (Id) values (newid())"; 
using (DBExecutor dbExecutor = userConnection.EnsureDBConnection())
{
	var reader = customQuery.ExecuteReader(dbExecutor);
}
return true;

 

Виталий Егоров пишет:
В БП этот код вызывает ошибку компиляции "The name dbExecutor does not exist in the current context"

Нужно обернуть в using, как и в первом фрагменте. 

 Либо "The type or namespace name 'IDataReader' coul not be found" в первом варианте.

А тут нужно включить нужную библиотеку System.Data в Usings (в дизайнере БП справа на вкладке «Методы»).

Спасибо, Алла, все работает.

Александр, спасибо, попробую добавить DataReader.

Добавил в этот же БП еще один сценарий с кодом:

foreach (string accountId in accountIdList){
    try {
        var update = new Update(UserConnection, "Account")
               .Set("OwnerId", Column.Parameter(newOwner))
               .Where ("Id").IsEqual(Column.Parameter(accountId));
        update.Execute();
    }
    catch (SqlException ex){
        errorsList.Add(ex.Message);
    }
    finally {
        var sel = new Select(UserConnection)
            .Column("Name")
            .From("Account")
            .Where ("Id").IsEqual(Column.Parameter(accountId));
             using (DBExecutor dbExecutor = context.UserConnection.EnsureDBConnection()) {
            using (IDataReader dataReader = sel.ExecuteReader(dbExecutor)){
                       accountName = CreateJson(dataReader);
            }
        }
        accountNameList.Add(accountName);
    }
}

На выходе получаю ошибку:

'Query' does not contain a definition for 'ExecuteReader' and no extension method 'ExecuteReader' accepting a first argument of type 'Query' could be found (are you missing a using directive or an assembly reference?)

 

 

Может, дело в забытом «as Select» в конце объявления sel? Как тут:

Select select = 
	new Select(UserConnection)
		.Column("Id")
		.From("ActivityStatus")
		.Where("Finish").IsEqual(Column.Parameter(true))
		as Select;
using (var dbExecutor = UserConnection.EnsureDBConnection()) {
	using (IDataReader dr = select.ExecuteReader(dbExecutor)) {
		while (dr.Read()) {
			finishActivityStatuses.Add(UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));
		}
	}
}

 

Спасибо, добрый человек! :)

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

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

У меня такой же вопрос

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

Для вывода сообщения используется функция:

Terrasoft.MessageBox.Show({message:'текст',title:'заголовок'})

 

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

Это понятно как выводить сообщения. Интересует вывод после завершения синхронизации данных.

Определить, загружались ли вообще по синхронизации данные, можно посредством:

!Ext.isEmpty(Terrasoft.CurrentUserInfo.lastSyncDate)

А первый или не первый раз, самому где-то хранить значение-флажок.

Войдите или зарегистрируйтесь, чтобы комментировать