Создание детали с несколькими типами и выпадающим списком на кнопке "Add" для BPM 7.5

BPM 7.5. Есть раздел Candidates, сущность UsrCandidates. Нужно для кандидата добавить деталь AddressOfCandidate, при этом необходимо, чтобы при нажатии на кнопку Add мы не переходили сразу на страницу заполнения полей, а чтобы выпадал список с типом адреса, и только при выборе типа мы переходили на страницу заполнения, где тип адреса уже выбран. Подобная стандартная деталь есть в разделе Contacts. Еще в стадии освоения BPM, трудно понять последовательность действий, особенно учитывая тормоза при открытии сохранении и глюки. Почти все примеры в инете для предыдущих версий. Где то используется генератор клиентского кода, который уже отсутствует в 7.5. Версия BPM англифицированная, поэтому возникают трудности соответсвия названий в примерах на русском и поиск соответствия на английском в названиях элементов, пунктов менЮ классов и т.п. Очень не хватает актуальных для 7.5 обучающих видео для "разработчиков", с использованием соотв. терминологии. Во многих видео приложения не видать, одни слайды с информацией, бесполезной для разработчика, и непонятной "кухарке-менеджеру". В некоторых дейтствительно потенциально полезных вебинарах на youtube отвратительный звук, или половина ролика - черный экран. Странный подход..

Addresses detail in Candidates

Опишите, пожалуйста, шаги, необходимые для создания подобной детали от начала до конца, для BPM 7.5.

Нравится

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

Реализация подобной логики практически не отличается от стандартной. Вся тонкость заключается в том, что Вам необходимо создать несколько карточек редактирования (под каждый необходимый тип). А затем убедиться в том, что в таблице SysModuleEdit созданы записи под ваши карточки редактирования с одинаковым значением колонки SysModuleEntityId, а в колонках TypeColumnValue указаны типы, все остальное за вас сделает логика программы.

Или реализовать, что-то на подобии “Знаменательные события” (BaseAnniversaryDetailV2) (она проще чем BaseAddressDetailV2)

"Киричатый Иван Владимирович" написал:Реализация подобной логики практически не отличается от стандартной.

Проблема в том, что я только разбираюсь в BPM, и для меня еще нет "стандартной логики", пока всё нестандартное :(

trickbz Вам давали ссылки на материалы по созданию деталей:

http://www.community.terrasoft.ru/developer/faq/1904

#22 Бондарь Наталия 17 мая 2015 – 20:44
trickbz, материал по созданию деталей уже есть, ниже ссылки:
1. Видеоурок.
2. Текстовое описание.

Если у возникают "проблемы" при просмотре видео, советую Вам смотреть в Mozilla Firefox

Спасибо за ответ,

Однако, информация по ссылкам годится только для создания простейших деталей.
Инструкция по адресу ниже не для детали, а для раздела, более того, релевантна лишь до версии 7.2, у меня же 7.5!
http://www.terrasoft.ru/bpmonlinesdk/CreateStandartSection.html#NUIShem…

Опишите, пожалуйста, подробно, как создать деталь, аналогичную стандартной детали для раздела "Contacts" "Noteworthy events", с выпадающим списком типа записи. Как создавать объект, какие страницы создавать, какой код в них вставлять (И не забудьте, что NUIShemaGenerator не существует для 7.5!), как их регистрировать в системе с помощью хранимой процедуры. Туториал, следая которому, можно создать рабочую деталь с нуля. Думаю такой туториал будет полезен многим.

Заранее спасибо и простите за настойчивость.

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

1. Создать объект с колонкой, например, «Type» (тип справочник) и соответственно создать затем деталь с необходимыми колонками, а также с одной страницей редактирование через мастер деталей.
2. Создаете несколько страниц редактирования (например, EmailPageV2) через конфигурацию;
3. Далее необходимо зарегистрировать страницы в БД. Для регистрации страницы редактирования необходимо воспользоваться хранимой процедурой «tsp_registerPage», которая находиться в БД.

Пример tsp_registerPage:

EXEC [dbo].[tsp_RegisterPage]
             @ModuleEntityName = N'Activity', - название объекта (например, «Деталь»)
             @PageName = N'TaskPage', - название страницы редактирования (например, «E-mail»)
             @TypeColumnUId =  '00000000-0000-0000-0000-00000000000000', – UId колонки тип в объекте (UID находим через метаданные объекта по названию колонки (например, Type)
             @TypeValue = '00000000-0000-0000-0000-00000000000000', - Id типа задача (ID записи, например, E-mail)
             @AddMenuCaptionRus = 'Добавить задачу',
             @AddMenuCaptionEng = 'Add Task',
             @CardHeaderCaptionRus = 'Задача',
             @CardHeaderCaptionEng = 'Task'

4. В итоге на деталь должно добавиться отобразиться несколько записей.

Более детально про tsp_registerPage (хранимая процедура) можете ознакомиться на SDK (инструкция по созданию раздела применима до версий 7.2)
http://www.terrasoft.ru/bpmonlinesdk/CreateStandartSection.html#NUIShem…

Ресурс SDK (http://www.terrasoft.ru/bpmonlinesdk/) можно использоваться для общего ознакомления, если у Вас версия выше, чем 7.3. но не использовать как пошаговую инструкцию.

Создание детали происходит через «Мастер детали». Создание страниц и объектов Вы можете использовать примеры базовых объектов (например, ContactAddressPageV2).
Также хотелось бы отметить, если у Вас возникли сложности при работе с базовым функционалом, то мы предоставляем курсы обучения по продукту.

Пример создания страницы редактирования есть в комментариях - http://www.community.terrasoft.ru/forum/topic/10247.

Информацию об объектах можете ознакомиться на SDK.
http://academy.terrasoft.ru/documents/?product=SDK&ver=7.5.0

Кажется начинает проясняться, но еще не до конца. Опишу, как я понимаю, на примере гипотетической задачи. При этом не будет существовать базовых объектов и страниц. Прошу прояснить пункт 6.
Задача:
Есть существующий раздел "User stories". Для раздела "User stories" необходимо добавить деталь "Issues", в которой можно создавать сущности "Bug" и "Enhancement request".
Алгоритм:
1. Создать объект "IssueType" от base lookup object.
2. В админке в разделе "Lookups" создать лукап "Issue type", в качестве объекта выбрать "IssueType".
3. Добавить в лукап "Issue type" две записи - "Bug" и "Enhancement request".
4. Создать объект "Issue", добавить необходимые для сущности поля ("Summary", "Description", "Severity", etc.), а также добавить лукапную колонку "Type", которая ссылается на "IssueType".
5. В мастере деталей создать деталь "Issue of user story".
5.1. В секции "Detail" в качестве объекта указать "Issue"
5.2. В секции "Page" перетаскивания колонки, которые будут отображаться на странице редактирования детали.
5.3. Сохраняю. При этом в конфигурации автоматически создаётся страница, содержащая разметку страницы редактирования детали с непонятным автоматически сгенерированным названием и кэпшном.
6. Далее, как я понимаю, нужно создать страницы редактирования для каждого типа. Тут у меня еще есть непонимание.
6.1. На шаге 5.3. у нас автоматически создалась страница редактирования с разметкой. Что с ней делать? Она нужна? Её нужно исползовать как базовую? Или код из неё можно скопировать в страницы редактирования каждого типа и подправить? Почему для неё сгенерировался непонятный caption "Client Schema1", нужно после создания менять вручную, баг?
6.2. Какой должен быть контент страниц редактирования для каждого типа? Должен ли я создавать разметку заново, либо могу ипользовать разметку из страницы шага 5.3? Должен ли я писать какой либо JavaScript код, чтобы на кнопке Add появился drop down с типом, и чтобы он автоматически выбрался на странице редактирования? Обязательно ли создавать НЕСКОЛЬКО страниц редактирования, если всё, чем они будут отличаться, это значением в поле Type?
7. Дальнейшие шаги вроде понятны.

Добрый день!

"trickbz" написал:6. Далее, как я понимаю, нужно создать страницы редактирования для каждого типа. Тут у меня еще есть непонимание.
6.1. На шаге 5.3. у нас автоматически создалась страница редактирования с разметкой. Что с ней делать? Она нужна? Её нужно исползовать как базовую? Или код из неё можно скопировать в страницы редактирования каждого типа и подправить? Почему для неё сгенерировался непонятный caption "Client Schema1", нужно после создания менять вручную, баг?
6.2. Какой должен быть контент страниц редактирования для каждого типа? Должен ли я создавать разметку заново, либо могу ипользовать разметку из страницы шага 5.3? Должен ли я писать какой либо JavaScript код, чтобы на кнопке Add появился drop down с типом, и чтобы он автоматически выбрался на странице редактирования? Обязательно ли создавать НЕСКОЛЬКО страниц редактирования, если всё, чем они будут отличаться, это значением в поле Type?

6.1 да нужна, она и будет базовой, если ее вид подходит для всех типов - ничего не нужно больше копировать, создавать или менять
6.2 «Add появился drop down с типом» появится автоматически, когда несколько страниц редактирования в таблице SysModuleEdit будут смотреть на одну и ту же сущность. На данный момент, к сожалению, нет «пользовательского визарда» для создания подобного. Разработчикам приходиться вручную копировать строки в таблице SysModuleEdit, а затем их регистрировать (Описание этих процедур приведено выше )

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

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

USE [ter-test]
GO
/****** Object:  StoredProcedure [dbo].[tsp_RegisterPage]    Script Date: 6/2/2015 9:42:42 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[tsp_RegisterPage] 
       @ModuleEntityName NVARCHAR(255),
       @PageName NVARCHAR(255),
       @TypeColumnUId NVARCHAR(255),
       @TypeValue NVARCHAR(255),
       @AddMenuCaptionRus NVARCHAR(255),
       @AddMenuCaptionEng NVARCHAR(255),
       @CardHeaderCaptionRus NVARCHAR(255),
       @CardHeaderCaptionEng NVARCHAR(255)
AS
BEGIN
       SET NOCOUNT ON;
 
       declare @SysModuleEntityId NVARCHAR(255);
       set @SysModuleEntityId = (select top 1 Id from SysModuleEntity where SysEntitySchemaUId = (select top 1 [UId] from SysSchema where Name = @ModuleEntityName))
 
       IF (@SysModuleEntityId IS NULL)
       BEGIN
       -- 1 Этап Создание записи SysModuleEntity
         INSERT into SysModuleEntity(SysEntitySchemaUId, TypeColumnUId) values((SELECT TOP 1 [UId] FROM SysSchema WHERE Name = @ModuleEntityName), @TypeColumnUId)  
       END
 
       -- 3 Этап Создание записи SysModuleEdit
       insert INTO SysModuleEdit
       (SysModuleEntityId,UseModuleDetails,CardSchemaUId, TypeColumnValue) VALUES
       ((SELECT Id from SysModuleEntity where SysEntitySchemaUId = (SELECT TOP 1 [UId] FROM SysSchema WHERE Name = @ModuleEntityName)),
       1,(select TOP 1 UId from SysSchema where Name = @PageName), @TypeValue)
 
       if (@AddMenuCaptionRus <> '')
       begin
             -- 7
             if (exists (select 1 from SysCulture where Id = '1A778E3F-0A8E-E111-84A3-00155D054C03'))
             begin
                    insert into SysModuleEditLcz (RecordId,ColumnUId,SysCultureId,Value)
                    values ((select Id from SysModule where Code = @ModuleEntityName),
                    'A19BF4BF-E22B-49B5-B6E0-918FF6290020', '1A778E3F-0A8E-E111-84A3-00155D054C03',       @AddMenuCaptionRus);
             end
             -- 8
             if (exists (select 1 from SysCulture where Id = 'A5420246-0A8E-E111-84A3-00155D054C03'))
             begin
             insert into SysModuleEditLcz (RecordId,ColumnUId,SysCultureId,Value)
                    values       ((select Id from SysModule where Code = @ModuleEntityName),
                    'A19BF4BF-E22B-49B5-B6E0-918FF6290020', 'A5420246-0A8E-E111-84A3-00155D054C03', @AddMenuCaptionEng);
             end
       end
 
 
       if (@CardHeaderCaptionRus <> '')
       begin
             -- 7
             if (exists (select 1 from SysCulture where Id = '1A778E3F-0A8E-E111-84A3-00155D054C03'))
             begin
                    insert into SysModuleEditLcz (RecordId,ColumnUId,SysCultureId,Value)
                    values ((select Id from SysModule where Code = @ModuleEntityName),
                    '55132174-2B96-4E0A-830C-B8E952B12C45', '1A778E3F-0A8E-E111-84A3-00155D054C03',       @CardHeaderCaptionRus);
             end
             -- 8
             if (exists (select 1 from SysCulture where Id = 'A5420246-0A8E-E111-84A3-00155D054C03'))
             begin
             insert into SysModuleEditLcz (RecordId,ColumnUId,SysCultureId,Value)
                    values       ((select Id from SysModule where Code = @ModuleEntityName),
                    '55132174-2B96-4E0A-830C-B8E952B12C45', 'A5420246-0A8E-E111-84A3-00155D054C03', @CardHeaderCaptionEng);
             end
       end
 
END

Смущают подобные строки

-- Версия то у нас английская, однако странновато выглядит. Ну да ладно, русскую локализацию я указывал, попадаём в IF.
IF (@CardHeaderCaptionRus <> '')
IF (@AddMenuCaptionRus <> '')
-- Эта строка смущает куда больше, т.к. в качестве @ModuleEntityName, как я понял, нужно указывавть имя объекта детали, а не раздела. И его не будет в колонке Code таблицы SysModule, там только объект разделов. Т.е. Record ID в SysModuleEditLcz будет NULL. И вообще, та ли эта таблица, куда должны записываться значения @AddMenuCaptionEng и @CardHeaderCaptionEng?
SELECT Id FROM SysModule WHERE Code = @ModuleEntityName

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

Всё, что у меня получилось сделать с помощью этой процедуры - на кнопке "Add" появился drop-down с пустыми пунктами.

ыы

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

http://youtu.be/cAt8joH7f4E

Действительно, Вы правы, процедура tsp_RegisterPage в разрезе вашей задачи работает некорректно – не проставляет правильные текстовые значения, в данной ситуации советуем вам отсортировать записи таблиц SysModuleEdit и SysModuleEditLcz и с помощью команды MsSql update обновить пустые значения колонок на нужные вам.

По поводу - нужно зайти в конфигурации на модуль вашей детали и установить нужно значение, сейчас там стоит Detail name

Алилуя!

Наконец-то разобрался, модифицировав существующую tsp_RegisterPage процедуру, которая НЕ ПОДХОДИТ для регистрации страниц редактирования деталей с несколькими типами, и которую при этом поддержка посылает пользователям с подобными вопросами. В некоторых совсем мелких моментах еще не разобрался, поэксперементирую завтра. Разработчикам рекомендую разобраться, что происходит в этой процедуре, в общем то для меня полезно было.

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

Несколько моментов

0. Писалось для BPM 7.5, на других не тестировалось.
1. Процедура рассчитана на англифицированную версию BPM, и значения @actionKindCaption, @actionKindName, @pageCaption добавляются только для культур en-GB, en-US (таблица SysCulture). Если нужные другие культуры, нужно модифицировать процедуру. Однако я написал комменты ко всем действиям и дал говорящие названия переменным, думаю пользователи разберуться, правда нужны скилы SQL и небольшие знания таблиц BPM.
2. Процедура удаляет запись / записи из таблицы SysModuleEdit, которые соответствуют записи из SysModuleEntity, которая ссылается UId объекта детали, и при этом у которых значение колонки TypeColumnValue равно NULL. Т.е., предпологается, что эта запись была создана автоматически при создании детали, однако, она не подходит для детали с несколькими типами.
3. После создания детали "стандартным способом" автоматически создаётся одна страница редактирования. Если она подходит для всех типов, то её одну можно зарегистрировать для всех типов, вызывав процедуру столько раз, сколько типов в детали. Если же нужны разные страницы редактирования для каждого типа, подозреваю, что можно просто её "скопировать" для нужных (или всех) типов, подправить разметку или добавить JavaScript, и зарегистрировать с помощью этой процедуры для всех типов, передавая имя нужной страниц из скопированных (и GUID типа), опять же, столько раз, сколько типов в детали. Но я не пробовал этого делать.
4. Естественно, процедура далека до совершенства. Например, можно было бы улучшить error handling, etc.

Вызывать так

Вызывать по разу для кадого типа, меняя @typeValue, @pageNameForSpecificType (при необходимости иметь разные странцы для разных типов), @itemPosition, @actionKindCaption, @actionKindName.

EXEC [dbo].[tsp_RegisterDetailPage]
@detailObjectName = 'UsrIssue' -- имя объекта, указанного при создании детали
,@typeColumnUid = '00000000-0000-0000-0000-000000000000' -- UId колонки объекта детали, отвечающей за тип, смотрим в метаданных
,@typeValue = '00000000-0000-0000-0000-000000000000' -- Значение одного из типов из таблицы, на которую ссылается колонка типа
,@pageNameForSpecificType = 'UsrUsrIssue1PageV2' -- имя страницы редактирования для @typeValue
,@itemPosition = 0 -- позиция элемента в выпадающем меню кнопки "Add" детали
,@actionKindCaption = 'Bug' -- Название пункта меню
,@actionKindName = 'Bug' -- Не знаю что, пусть будет
,@pageCaption = 'Bug' -- Заголовок страницы редактирования

Код

Приатачиваю файл tsp_registerdetailpage.txt
и выкладываю полотно.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[tsp_RegisterDetailPage]
	@detailObjectName nvarchar(255)
	,@typeColumnUid uniqueidentifier
	,@typeValue uniqueidentifier
	,@pageNameForSpecificType nvarchar(255)
	,@itemPosition int
	,@actionKindCaption nvarchar(255)
	,@actionKindName nvarchar(255)
	,@pageCaption nvarchar(255)
AS
BEGIN
	SET NOCOUNT ON;
 
	-- Step 1. Declare constants
	declare @cultureUnitedKindomId uniqueidentifier = 'A5420246-0A8E-E111-84A3-00155D054C03';
	declare @cultureUnitedStatesId uniqueidentifier = 'D294EECE-62E7-46DA-ACA3-381D2E825C7D';
	declare @pageCaptionElementId uniqueidentifier = '55132174-2B96-4E0A-830C-B8E952B12C45'; -- TODO: Know from which table and if correct.
	declare @actionKindCaptionElementId uniqueidentifier = 'A19BF4BF-E22B-49B5-B6E0-918FF6290020';
 
	-- Step 2. Initializing variables
	declare @currentDateTime datetime = GETDATE();
	declare @detailObjectUid uniqueidentifier = (select top 1 UId from SysSchema ss where ss.Name = @detailObjectName);
	declare @cardSchemaUId uniqueidentifier = (select top 1 UId from SysSchema where Name = @pageNameForSpecificType);
	declare @userId uniqueidentifier = (select top 1 CreatedById from SysSchema where [UId] = @detailObjectUid);
 
	-- Step 3. Getting SysModuleEntity Id and updating a record with @typeColumnUid
	declare @moduleEntityId uniqueidentifier = (select Id from SysModuleEntity sme where sme.SysEntitySchemaUId = @detailObjectUid);
	if (@moduleEntityId is null)
		begin
			insert into SysModuleEntity(SysEntitySchemaUId, TypeColumnUId) VALUES(@detailObjectUid, @TypeColumnUId);
			set @moduleEntityId = (select top 1 Id from SysModuleEntity where SysEntitySchemaUId = @detailObjectUid);
		end
	else
		update SysModuleEntity set TypeColumnUId = @typeColumnUid where Id = @moduleEntityId;
 
	-- Step 4. Deleting SysModuleEdit records related to the @moduleEntityId if TypeColumnValue is null
	-- Most probably these records were created during creating of detail from UI.
	delete from SysModuleEdit where SysModuleEntityId = @moduleEntityId and TypeColumnValue is null;
 
	-- Step 5. Inserting a new record to SysModuleEdit to register @pageNameForSpecificType for @typeValue type.
	insert into SysModuleEdit
	(
		CreatedOn, 
		CreatedById, 
		ModifiedOn, 
		ModifiedById, 
		SysModuleEntityId, 
		TypeColumnValue, 
		UseModuleDetails, 
		Position, 
		CardSchemaUId, 
		ActionKindCaption, 
		ActionKindName, 
		PageCaption
	)
	values
	(
		@currentDateTime,
		@userId,
		@currentDateTime,
		@userId,
		@moduleEntityId,
		@typeValue,
		1,
		@itemPosition,
		@cardSchemaUId,
		@actionKindCaption,
		@actionKindName,
		@pageCaption
	);
 
	-- Step 6. Storing just created SysModuleEdit record Id, it's used in next localization steps
	declare @moduleEditRecordId uniqueidentifier = (select top 1 Id from SysModuleEdit where CardSchemaUId = @cardSchemaUId and TypeColumnValue = @typeValue);
 
	-- Step 7. Insert localozation values for [United Kindom] (if such culture exists)
	if (exists (select 1 from SysCulture where Id = @cultureUnitedKindomId))
	begin
		-- Step 7.1. Action kind caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @actionKindCaptionElementId, @cultureUnitedKindomId, @actionKindCaption);
		-- Step 7.2. Card header caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @pageCaptionElementId, @cultureUnitedKindomId, @pageCaption);
	end
 
	-- Step 8. Insert localozation values for [United States] (if such culture exists)
	if (exists (select 1 from SysCulture where Id = @cultureUnitedStatesId))
	begin
		-- Step 8.1. Action kind caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @actionKindCaptionElementId, @cultureUnitedStatesId, @actionKindCaption);
		-- Step 8.2. Card header caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @pageCaptionElementId, @cultureUnitedStatesId, @pageCaption);
	end
END

Немного улучшил

Функция для получения UId колонки (например, типа детали, а вообще любой) по имени таблицы и имени колонки. Чтобы избавить от лазания по метаданным. В общем всё можно вытянуть SQL запросом.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[GetColumnUId]
(
        @tableName nvarchar(255)
        ,@columnName nvarchar(255)
)
RETURNS uniqueidentifier
AS
BEGIN
        declare @columnUId uniqueidentifier;
 
        SELECT @columnUId= CONVERT(uniqueidentifier, value)
        FROM sys.extended_properties AS ep
        INNER JOIN sys.TABLES AS t ON ep.major_id = t.object_id
        INNER JOIN sys.COLUMNS AS c ON ep.major_id = c.object_id AND ep.minor_id = c.column_id
        WHERE 
                class = 1
                AND ep.name = 'TS.EntitySchemaColumn.UId'
                AND t.name = @tableName
                AND c.name = @columnName
        ORDER BY t.name;
 
        RETURN @columnUId;
END
GO

Код хранимой процедуры с учётом функции выше

USE [bpm-eng]
GO
/****** Object:  StoredProcedure [dbo].[tsp_RegisterDetailPage]    Script Date: 6/4/2015 4:42:41 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[tsp_RegisterDetailPage]
	@detailObjectName nvarchar(255)
	,@typeColumnName nvarchar(255)
	,@typeValue uniqueidentifier
	,@pageNameForSpecificType nvarchar(255)
	,@itemPosition int
	,@actionKindCaption nvarchar(255)
	,@actionKindName nvarchar(255)
	,@pageCaption nvarchar(255)
AS
BEGIN
	SET NOCOUNT ON;
 
	-- Step 1. Declare constants
	declare @cultureUnitedKindomId uniqueidentifier = 'A5420246-0A8E-E111-84A3-00155D054C03';
	declare @cultureUnitedStatesId uniqueidentifier = 'D294EECE-62E7-46DA-ACA3-381D2E825C7D';
	declare @pageCaptionElementId uniqueidentifier = '55132174-2B96-4E0A-830C-B8E952B12C45'; -- TODO: Know from which table and if correct.
	declare @actionKindCaptionElementId uniqueidentifier = 'A19BF4BF-E22B-49B5-B6E0-918FF6290020';
 
	-- Step 2. Initializing variables
	declare @currentDateTime datetime = GETDATE();
	declare @detailObjectUid uniqueidentifier = (select top 1 UId from SysSchema ss where ss.Name = @detailObjectName);
	declare @cardSchemaUId uniqueidentifier = (select top 1 UId from SysSchema where Name = @pageNameForSpecificType);
	declare @userId uniqueidentifier = (select top 1 CreatedById from SysSchema where [UId] = @detailObjectUid);
	declare @typeColumnUid uniqueidentifier = [dbo].[GetColumnUId](@detailObjectName,@typeColumnName);
 
	-- Step 3. Getting SysModuleEntity Id and updating a record with @typeColumnUid
	declare @moduleEntityId uniqueidentifier = (select Id from SysModuleEntity sme where sme.SysEntitySchemaUId = @detailObjectUid);
	if (@moduleEntityId is null)
		begin
			insert into SysModuleEntity(SysEntitySchemaUId, TypeColumnUId) VALUES(@detailObjectUid, @TypeColumnUId);
			set @moduleEntityId = (select top 1 Id from SysModuleEntity where SysEntitySchemaUId = @detailObjectUid);
		end
	else
		update SysModuleEntity set TypeColumnUId = @typeColumnUid where Id = @moduleEntityId;
 
	-- Step 4. Deleting SysModuleEdit records related to the @moduleEntityId if TypeColumnValue is null
	-- Most probably these records were created during creating of detail from UI.
	delete from SysModuleEdit where SysModuleEntityId = @moduleEntityId and TypeColumnValue is null;
 
	-- Step 5. Inserting a new record to SysModuleEdit to register @pageNameForSpecificType for @typeValue type.
	insert into SysModuleEdit
	(
		CreatedOn, 
		CreatedById, 
		ModifiedOn, 
		ModifiedById, 
		SysModuleEntityId, 
		TypeColumnValue, 
		UseModuleDetails, 
		Position, 
		CardSchemaUId, 
		ActionKindCaption, 
		ActionKindName, 
		PageCaption
	)
	values
	(
		@currentDateTime,
		@userId,
		@currentDateTime,
		@userId,
		@moduleEntityId,
		@typeValue,
		1,
		@itemPosition,
		@cardSchemaUId,
		@actionKindCaption,
		@actionKindName,
		@pageCaption
	);
 
	-- Step 6. Storing just created SysModuleEdit record Id, it's used in next localization steps
	declare @moduleEditRecordId uniqueidentifier = (select top 1 Id from SysModuleEdit where CardSchemaUId = @cardSchemaUId and TypeColumnValue = @typeValue);
 
	-- Step 7. Insert localozation values for [United Kindom] (if such culture exists)
	if (exists (select 1 from SysCulture where Id = @cultureUnitedKindomId))
	begin
		-- Step 7.1. Action kind caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @actionKindCaptionElementId, @cultureUnitedKindomId, @actionKindCaption);
		-- Step 7.2. Card header caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @pageCaptionElementId, @cultureUnitedKindomId, @pageCaption);
	end
 
	-- Step 8. Insert localozation values for [United States] (if such culture exists)
	if (exists (select 1 from SysCulture where Id = @cultureUnitedStatesId))
	begin
		-- Step 8.1. Action kind caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @actionKindCaptionElementId, @cultureUnitedStatesId, @actionKindCaption);
		-- Step 8.2. Card header caption
		insert into SysModuleEditLcz (RecordId, ColumnUId, SysCultureId, Value)
		values (@moduleEditRecordId, @pageCaptionElementId, @cultureUnitedStatesId, @pageCaption);
	end
END

Пример вызова для регистрации одной страницы редактирования для всех типов. Лучше пробовать сначала на тестовом сервере во избежании захламления БД в случае ошибки :wink:
declare @detailObjectName nvarchar(255) = 'UsrComOptionsCand';
declare @typeColumnName nvarchar(255) = 'CommunicationTypeId'; -- don't forget to add Id at the end for lookup fields
declare @pageNameForSpecificType nvarchar(255) = 'UsrUsrComOptionsCand1PageV2';
 
declare @typeValueTemp uniqueidentifier, @typeNameTemp nvarchar(255), @counter int = 0;
declare cursorTypes cursor for select Id, Name from CommunicationType;
open cursorTypes;
fetch next from cursorTypes into @typeValueTemp, @typeNameTemp;
while @@FETCH_STATUS = 0
begin
	EXEC [dbo].[tsp_RegisterDetailPage]
		@detailObjectName = @detailObjectName
		,@typeColumnName = @typeColumnName
		,@typeValue = @typeValueTemp
		,@pageNameForSpecificType = @pageNameForSpecificType
		,@itemPosition = @counter
		,@actionKindCaption = @typeNameTemp
		,@actionKindName = @typeNameTemp
		,@pageCaption = @typeNameTemp;
	set @counter = @counter + 1;
	fetch next from cursorTypes into @typeValueTemp, @typeNameTemp;
end
 
close cursorTypes;
deallocate cursorTypes;

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