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

Ссылка на решение

Вся основная логика лежит на хранимых процедурах: tsp_DeleteSysProcessDataById, tsp_DeleteSysProcessDataByStartDate, tsp_UpdateSysProcessLogById, tsp_UpdateSysProcessLogByStartDate

В общих словах про процедуры

tsp_DeleteSysProcessDataById – удаляет информацию по процессу из таблиц SysActivityPrcEl, SysEntityCommonPrcEl, SysProcessIntermediateEvent, SysProcessData

tsp_DeleteSysProcessDataByStartDate – читает процессы, в логе фильтрует по дате, и запускает DeleteSysProcessDataById 

tsp_UpdateSysProcessLogById – обновляет информацию по процессу из таблиц SysProcessLog, SysProcessElementLog,

tsp_UpdateSysProcessLogByStartDate – читает процессы, в логе фильтрует по дате, и запускает UpdateSysProcessLogById

Бизнес-процесс который позволяет выбрать процесс, указать период, отменить процессы и выдать результат (к-ство отменных процессов)

Ниже отдельно SQL скрипты самих процедур

Скрипт на удаление:

SET QUOTED_IDENTIFIER ON
GO
 
IF NOT OBJECT_ID('[dbo].[tsp_DeleteSysProcessDataById]') IS NULL
BEGIN
	DROP PROCEDURE [dbo].[tsp_DeleteSysProcessDataById]
END
GO
 
CREATE PROCEDURE [dbo].[tsp_DeleteSysProcessDataById]
	@SysProcessDataId uniqueidentifier
AS
BEGIN
 
	SET NOCOUNT ON
 
	DECLARE @sysProcessDataRecordsToDelete TABLE (Id uniqueidentifier)
	DECLARE @sysProcessElementDataRecordsToDelete TABLE (Id uniqueidentifier )
 
	INSERT INTO @sysProcessDataRecordsToDelete ([Id])
		SELECT Id from SysProcessData
		WHERE ParentId = @SysProcessDataId
	OPTION (OPTIMIZE FOR (@SysProcessDataId UNKNOWN))
 
	DECLARE @COUNT bigint = (SELECT COUNT_BIG(*) FROM @sysProcessDataRecordsToDelete)
	WHILE (@COUNT) != 0
		BEGIN
			DECLARE @parentId uniqueidentifier = (SELECT TOP 1 Id from @sysProcessDataRecordsToDelete)
			DELETE FROM @sysProcessDataRecordsToDelete WHERE Id = @parentId;
			EXEC [dbo].[tsp_DeleteSysProcessDataById] @parentId
			SET @COUNT = @COUNT - 1
		END
 
	INSERT INTO @sysProcessElementDataRecordsToDelete ([Id])
		SELECT Id FROM SysProcessElementData
		WHERE SysProcessId = @SysProcessDataId
	SET @COUNT = (SELECT COUNT_BIG(*) FROM @sysProcessElementDataRecordsToDelete)
	DELETE FROM SysActivityPrcEl WHERE ProcessElementId IN (SELECT Id FROM @sysProcessElementDataRecordsToDelete)
	DELETE FROM SysEntityCommonPrcEl WHERE ProcessElementId IN (SELECT Id FROM @sysProcessElementDataRecordsToDelete)
	DELETE FROM SysProcessIntermediateEvent WHERE SysProcessElementId IN (SELECT Id FROM @sysProcessElementDataRecordsToDelete)
	DELETE FROM SysProcessData WHERE Id = @SysProcessDataId
	OPTION (OPTIMIZE FOR (@SysProcessDataId UNKNOWN))
END
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
IF NOT OBJECT_ID('[dbo].[tsp_DeleteSysProcessDataByStartDate]') IS NULL
BEGIN
	DROP PROCEDURE [dbo].[tsp_DeleteSysProcessDataByStartDate]
END
GO
 
CREATE PROCEDURE [dbo].[tsp_DeleteSysProcessDataByStartDate]
	@ProcessName nvarchar(MAX),
	@StartDate datetime,
	@EndDate datetime
AS
BEGIN
 
	SET NOCOUNT ON
 
	IF NOT OBJECT_ID('#SysProcessDataId') IS NULL
	BEGIN
		DROP TABLE #SysProcessDataId
	END
 
	CREATE TABLE #SysProcessDataId (Id uniqueidentifier)
 
	INSERT INTO #SysProcessDataId ([Id])
		SELECT DISTINCT SysProcessData.Id FROM SysProcessLog
		JOIN SysProcessData on SysProcessLog.SysSchemaId = SysProcessData.SysSchemaId
		WHERE SysProcessData.ParentId IS NULL
		AND CONVERT(date, SysProcessLog.StartDate) >= CONVERT(date, @StartDate) and CONVERT(date, SysProcessLog.StartDate) <= CONVERT(date, @EndDate) 
		AND SysProcessLog.Name = @ProcessName
		AND SysProcessLog.StatusId = 'ED2AE277-B6E2-DF11-971B-001D60E938C6'
 
	DECLARE SysProcessDataIdCursor CURSOR STATIC LOCAL FOR
	SELECT
		Id
	FROM 
		#SysProcessDataId
 
	DECLARE @COUNT int = (SELECT COUNT_BIG(*) FROM #SysProcessDataId)
 
	IF (@COUNT > 50000)
		SET @COUNT = 50000
 
	DECLARE @processDataId uniqueidentifier
 
	OPEN SysProcessDataIdCursor
	WHILE (@COUNT > 0)
		BEGIN
			FETCH NEXT FROM SysProcessDataIdCursor INTO @processDataId
			IF @@FETCH_STATUS = -1 BREAK
			IF @@FETCH_STATUS = -2 CONTINUE
			EXEC [dbo].[tsp_DeleteSysProcessDataById] @processDataId
			SET @COUNT = @COUNT - 1
		END
	CLOSE SysProcessDataIdCursor
	DEALLOCATE SysProcessDataIdCursor
 
	IF NOT OBJECT_ID('#SysProcessDataId') IS NULL
	BEGIN
		DROP TABLE #SysProcessDataId
	END
 
END
GO

Скрипт на обновление:

SET QUOTED_IDENTIFIER ON
GO
 
IF NOT OBJECT_ID('[dbo].[tsp_UpdateSysProcessLogById]') IS NULL
BEGIN
	DROP PROCEDURE [dbo].[tsp_UpdateSysProcessLogById]
END
GO
 
CREATE PROCEDURE [dbo].[tsp_UpdateSysProcessLogById]
	@SysProcessLogId uniqueidentifier
AS
BEGIN
 
	SET NOCOUNT ON
 
	DECLARE @sysProcessLogRecordsToDelete TABLE (Id uniqueidentifier)
 
	INSERT INTO @sysProcessLogRecordsToDelete ([Id])
		SELECT Id FROM SysProcessLog
		WHERE ParentId = @SysProcessLogId
	OPTION (OPTIMIZE FOR (@SysProcessLogId UNKNOWN))
 
	DECLARE @COUNT int = (SELECT COUNT(*) FROM @sysProcessLogRecordsToDelete)
	WHILE (@COUNT) != 0
		BEGIN
			DECLARE @parentId uniqueidentifier = (SELECT TOP 1 Id from @sysProcessLogRecordsToDelete)
 
			Update SysProcessLog 
			Set StatusId=( select id from SysProcessStatus where id = '1BE78F3E-234D-4D6A-869A-DC07253FD2F3' ) 
			Where id =@parentId
 
			EXEC [dbo].[tsp_UpdateSysProcessLogById] @parentId
			SET @COUNT = @COUNT - 1
		END
 
	Update SysProcessLog 
	Set CompleteDate = GETUTCDATE(), StatusId=( select id from SysProcessStatus where id = '1BE78F3E-234D-4D6A-869A-DC07253FD2F3' ) 
	Where id =@SysProcessLogId AND StatusId = 'ED2AE277-B6E2-DF11-971B-001D60E938C6'
 
 
	UPDATE SysProcessElementLog Set StatusId = (select Id from SysProcessStatus where Id = '1BE78F3E-234D-4D6A-869A-DC07253FD2F3'), CompleteDate = GETUTCDATE() where SysProcessId = @SysProcessLogId 
	and StatusId= 'ED2AE277-B6E2-DF11-971B-001D60E938C6' 
 
 
END
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
IF NOT OBJECT_ID('[dbo].[tsp_UpdateSysProcessLogByStartDate]') IS NULL
BEGIN
	DROP PROCEDURE [dbo].[tsp_UpdateSysProcessLogByStartDate]
END
GO
 
CREATE PROCEDURE [dbo].[tsp_UpdateSysProcessLogByStartDate]
	@ProcessName nvarchar(MAX),
	@StartDate datetime,
	@EndDate datetime
AS
BEGIN
 
	SET NOCOUNT ON
 
	IF NOT OBJECT_ID('#SysProcessLogId') IS NULL
	BEGIN
		DROP TABLE #SysProcessLogId
	END
 
	CREATE TABLE #SysProcessLogId (Id uniqueidentifier)
 
	INSERT INTO #SysProcessLogId ([Id])
		SELECT Top 100000 SysProcessLog.Id FROM SysProcessLog
		WHERE SysProcessLog.ParentId IS NULL
		AND CONVERT(date, SysProcessLog.StartDate) >= CONVERT(date, @StartDate) 
		AND CONVERT(date, SysProcessLog.StartDate) <= CONVERT(date, @EndDate) 
		AND SysProcessLog.Name = @ProcessName 
 
	CREATE TABLE #SysProcessExec (Id uniqueidentifier)
 
	INSERT INTO #SysProcessExec ([Id])
		SELECT Top 100000 SysProcessLog.Id FROM SysProcessLog
		WHERE SysProcessLog.ParentId IS NULL
		AND CONVERT(date, SysProcessLog.StartDate) >= CONVERT(date, @StartDate) 
		AND CONVERT(date, SysProcessLog.StartDate) <= CONVERT(date, @EndDate) 
		AND SysProcessLog.Name = @ProcessName 
		AND SysProcessLog.StatusId = 'ED2AE277-B6E2-DF11-971B-001D60E938C6'
 
	DECLARE SysProcessLogIdCursor CURSOR STATIC LOCAL FOR
	SELECT
		Id
	FROM 
		#SysProcessLogId
 
	DECLARE @COUNT int = (SELECT COUNT_BIG(*) FROM #SysProcessLogId)
 
	DECLARE @processLogId uniqueidentifier
 
	OPEN SysProcessLogIdCursor
	WHILE (@COUNT > 0)
		BEGIN
			FETCH NEXT FROM SysProcessLogIdCursor INTO @processLogId
			IF @@FETCH_STATUS = -1 BREAK
			IF @@FETCH_STATUS = -2 CONTINUE
			EXEC [dbo].[tsp_UpdateSysProcessLogById] @processLogId
			SET @COUNT = @COUNT - 1
		END
	CLOSE SysProcessLogIdCursor
	DEALLOCATE SysProcessLogIdCursor
	INSERT INTO MassCancellationProcessesLog (StartDate, EndDate, DisableProcessCount, Process)	VALUES(CONVERT(date, @StartDate), CONVERT(date, @EndDate), (SELECT COUNT(*) FROM #SysProcessExec), @ProcessName)
	IF NOT OBJECT_ID('#SysProcessLogId') IS NULL
	BEGIN
		DROP TABLE #SysProcessLogId
	END
	IF NOT OBJECT_ID('#SysProcessExec') IS NULL
	BEGIN
		DROP TABLE #SysProcessExec
	END
 
END
GO

 

Нравится

Поделиться

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

Симптомы

1) Проэкспортированные файлы в десктопе имеют 0 размер

2) В логе ошибок синхронизации есть такой текст:

Ошибка HTTP 405.0 - Method Not Allowed

Разыскиваемая вами страница не может быть отображена потому, что используется недопустимый метод (команда HTTP).

Причина

Неправильные настройки IIS

Решение

В web.config вносим изменения:

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>

Нравится

Поделиться

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

1. Добавить в конфигураторе в Custom - действие процесса

Заголовок: Звонок в CTI-панель

Название:UsrCtiPanelCallUserTask

Скрипт:

var message = "{\"number\": \"" + PhoneNumber + "\"}";
MsgChannelUtilities.PostMessage(UserConnection, "CtiPanelCallFromProcess", message);
return true;

Добавить в этом же юзер таске параметр

Название: PhoneNumber

Подпись: Номер телефона

Тип данных: строка

И добавить два Usings

    Terrasoft.Configuration
    Terrasoft.Core.Factories

2. Добавить  в конфигураторе в Custom - замещающий клиентский модуль

Родительский обьект: ClientMessageBridge

Скоприровать Название в Заголовок.

Сохранить

Вставить код:

define("ClientMessageBridge", [], function() {
    return {
        messages: {
            "CallCustomer": {
                "mode": Terrasoft.MessageMode.PTP,
                "direction": Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        methods: {
            init: function() {
                this.callParent(arguments);
                this.addMessageConfig({
                    sender: "CtiPanelCallFromProcess",
                    messageName: "CallCustomer"
                });
            },
            beforePublishMessage: function(sandboxMessageName, webSocketBody) {
                if (sandboxMessageName === "CallCustomer") {
                    // Здесь вставить дополнительный код, который будет выполняться перед звонком
                }
            },
            afterPublishMessage: function(sandboxMessageName, webSocketBody) {
                if (sandboxMessageName === "CallCustomer") {
                    // Здесь вставить дополнительный код, который будет выполняться после звонка
                }
            }
        }
    };
});

Сохранить

3. После конфигуратора в БП добавляем блок "Выполнить действие процесса", где выбираем: Звонок в CTI-панель

Указываем в параметре номер телефона для звонка.

Нравится

Поделиться

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

Вопрос

День добрый.

Версия 7.7

Мы вносим какие то изменения на страницу, к примеру Контрагента, вносим свои колонки, удаляем стандартные.

После, хотим вернуться к исходному варианту. К примеру через конфигуратор просто убиваем файл замещающей страницы, в предыдущих версиях это срабатывало, достаточно было почистить кэш и куки ну и откомпелировать все.

В данной версии, этого не достаточно, страница как была отредактирована, так она и осталась.

Как выйти из положения?

Ответ

Данное поведение связано с тем что начиная с версии 7.7 в BPM'Online используются бандлы, в которых содержатся все схемы страниц и разделов. Простое удаление замещающей схемы страницы раздела не изменяет бандл. Для возврата к исходной странице, Вам нужно создать пустой замещающий клиентский модуль для нужной Вам страницы. К примеру для страницы раздела "Лиды" он будет выглядеть так:

define("LeadPageV2", ["BusinessRuleModule", "ConfigurationConstants"],
    function(BusinessRuleModule, ConfigurationConstants) {
        return {};
});

Затем нужно сохранить созданный модуль и очистить кэш браузера.

Нравится

Поделиться

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

Симптомы

При добавлении продуктов в счет всплывает ошибка о том, что поле "Цена поставщика" обязательна к заполнению, но она заполнена. Значение в поле есть. 

Причина

Включено администрирование по колонкам для объекта "Счет" и на поле "Цена поставщика" у указанного пользователя нет права (не смотря на то, что поле заполняется автоматически).

Решение

Дать право на изменение колонки "Цена поставщика" нужному пользователю.

Нравится

Поделиться

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

Симптомы

Есть сущность, в ней несколько табов (e.g. Tab1 и Tab2), в табах field groups. Tab1 - первый слева направо, т.е. открыт по умолчанию, и видны поля. Нужно добавить поле в Tab2, закрытый / неактивный по умолчанию. Но не просто добавить, и менять скрывать / снова показывать по условию. Я это делаю путём биндинга функции на свойство "visible" в размете. Еслие поле на карточке (не в табе) или в первом (открытом) то всё работает. Если же поле находится в Tab2, то при открытии сущности бросается исключение.

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

Решение

Обходные решения: 

1) Использовать свойство элемента "enabled" вместо "visible", то есть, вместо того что бы скрывать поле, делать поле не редактируемым.

Недостаток: поле остаётся видимым.

Достоинство: решение совместимо с мастерами.

2) Вместо контейнера GRID_LAYOUT для скрываемого элемента в качестве контейнера использовать: CONTAINER, CONTROL_GROUP или ContainerList .

Недостаток: решение не совместимо с мастером и скорей всего потребует вмешательства разработчика. Достоинство: поле будет скрыто."

Нравится

Поделиться

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

Вопрос

Высоту поля "Решение" можно изменить?

Ответ

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

Алгоритм:

1. Заместить данный модуль.

2. Для колонки «Notes» (diff) добавить в секцию «values» или «controlConfig» свойство «"height": "размер в пикселях"»).

Пример кода:

{
    "operation": "merge",
    "name": "Notes",
    "values": {
        "height": "500px"  
    }
},

 

Нравится

Поделиться

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

Симптомы

При синхронизации/входе в раздел мобильного приложения у клиента возникает ошибка вида:

Тип: Terrasoft.SourceCodeException 

Сообщение: Uncaught TypeError: Cannot read property 'ColumnConfigs' of null 

Дополнительная информация: 

        Script: file:///android_asset/www/Common/Terrasoft.Mobile.Combined.js%0D%0A%09Line: 19048 

Calls sequence: 

    at Ext.define.showException (file:///android_asset/www/Common/Terrasoft.Mobile.Combined.js:33105:41

    at Ext.define.showUncaughtException (file:///android_asset/www/Common/Terrasoft.Mobile.Combined.js:1965:25

    at window.onerror (file:///android_asset/www/Common/Terrasoft.Mobile.Combined.js:1666:20)

Причина

Дублирование схем в манифесте

Решение

Вариант 1

Нужно в базовой схеме MobileApplicationManifest пакета Mobile изменить строчку

…
Models: {
    …
    Activity: {
        …
        RequiredModels: [
            'Contact''ActivityType''ActivityStatus',
            'ActivityResult''ActivityCategory''ActivityPriority', 'Contact', 
            'Account''Opportunity''Lead''ActivityParticipantRole',
            'ActivityParticipant''ActivityCategoryResultEntry''ActivityCorrespondence''Activity'

Убрать дублирующееся значение «Contact»

Вариант 2

Обновить мобильное приложение на более свежую версию

Необходимые условия и возможные ограничения

Версия BPMonline 7.1.0 - 7.5.0

Версия мобильного приложения:

   Android 7.6.2. - 7.6.3.

   iOS 7.6.2

Нравится

Поделиться

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

Симптомы

Тип: Terrasoft.ODataSecurityException%0D%0AСообщение: Недостаточно прав для изменения записи в объекте "Activity"%0D%0AДополнительная информация: %0D%0A%09{"error":{"code":"5","message":{"lang":"","value":"Недостаточно прав для изменения записи в объекте \"Activity\""},"innererror":{"message":"Недостаточно прав для изменения записи в объекте \"Activity\"","type":"System.Security.SecurityException","stacktrace":"   в Terrasoft.Core.Entities.Entity.UpdateInDB(Boolean validateRequired)\r\n   в Terrasoft.Core.Entities.Entity.Save(Boolean validateRequired)\r\n   в Terrasoft.Core.Entities.Services.EntityLazyProxy.SaveChanges()\r\n   в Terrasoft.Core.Entities.Services.ServiceContext.SaveChanges()\r\n   в System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)\r\n   в System.Data.Services.DataService`1.HandleRequest()"}}}%0D%0A%0D%0A

Тип: Terrasoft.ODataSecurityException%0D%0AСообщение: Недостаточно прав для изменения записи в объекте "Activity"%0D%0AДополнительная информация: %0D%0A%09{"error":{"code":"5","message":{"lang":"","value":"Недостаточно прав для изменения записи в объекте \"Activity\""},"innererror":{"message":"Недостаточно прав для изменения записи в объекте \"Activity\"","type":"System.Security.SecurityException","stacktrace":"   в Terrasoft.Core.Entities.Entity.UpdateInDB(Boolean validateRequired)\r\n   в Terrasoft.Core.Entities.Entity.Save(Boolean validateRequired)\r\n   в Terrasoft.Core.Entities.Services.EntityLazyProxy.SaveChanges()\r\n   в Terrasoft.Core.Entities.Services.ServiceContext.SaveChanges()\r\n   в System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)\r\n   в System.Data.Services.DataService`1.HandleRequest()"}}}%0D%0A%0D%0A

Тип: Terrasoft.ODataSecurityException%0D%0AСообщение: Недостаточно прав для изменения записи в объекте "Activity"%0D%0AДополнительная информация: %0D%0A%09{"error":{"code":"5","message":{"lang":"","value":"Недостаточно прав для изменения записи в объекте \"Activity\""},"innererror":{"message":"Недостаточно прав для изменения записи в объекте \"Activity\"","type":"System.Security.SecurityException","stacktrace":"   в Terrasoft.Core.Entities.Entity.UpdateInDB(Boolean validateRequired)\r\n   в Terrasoft.Core.Entities.Entity.Save(Boolean validateRequired)\r\n   в Terrasoft.Core.Entities.Services.EntityLazyProxy.SaveChanges()\r\n   в Terrasoft.Core.Entities.Services.ServiceContext.SaveChanges()\r\n   в System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)\r\n   в System.Data.Services.DataService`1.HandleRequest()"}}}%0D%0A%0D%0A

Причина

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

Решение

Для решения задачи следует:

1. Если пользователь раннее не был добавлен в конфигурацию, то необходимо перейти в меню “Управление конфигурацией”, “Администрирование: Доступ к объектам”, деталь “Доступ к записям по умолчанию: Изменение” и добавить пользователя\роль;

2. Выполнить действие “Актуализировать организационную структуру” (Рис. 1, пункт 1);

3. Раздать права доступа на объекты мобильного приложения ” (Рис. 1, пункт 2);

4. Выполнить повторную синхронизацию с мобильного устройства.   

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

Рис. 1

Необходимые условия и возможные ограничения

Доступ в систему под учетной записью пользователя с правами администратора.

Нравится

Поделиться

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

Симптомы:

Ошибка: Could not load file or assembly 'SharpSvn'

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

Причина:

При обновлении клиента с 7.11.3 на 7.12.0

Решение:

Новая настройка безопасности. Чтобы можно было запускать консоль с удаленных серверов нужно в app.config консоли добавить/отредактировть параметр:

true" />

Нравится

Поделиться

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