54 lines
3.0 KiB
Transact-SQL
54 lines
3.0 KiB
Transact-SQL
-- Change only hierarchy fields, preserving location details and aliases.
|
|
CREATE OR ALTER PROCEDURE dbo.Location_Reparent
|
|
@ProjectID int,
|
|
@LocationID int,
|
|
@ParentLocationID int,
|
|
@ExpectedParentLocationID int = NULL,
|
|
@UserID int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
SET XACT_ABORT ON;
|
|
BEGIN TRY
|
|
BEGIN TRANSACTION;
|
|
DECLARE @LockedProjectID int, @OldParentID int, @Name nvarchar(200), @ParentName nvarchar(200);
|
|
SELECT @LockedProjectID=ProjectID FROM dbo.Projects WITH (UPDLOCK,HOLDLOCK) WHERE ProjectID=@ProjectID AND IsArchived=0;
|
|
IF @LockedProjectID IS NULL OR @UserID IS NULL OR NOT EXISTS
|
|
(SELECT 1 FROM dbo.ProjectUserAccess WHERE ProjectID=@ProjectID AND UserID=@UserID AND IsActive=1)
|
|
THROW 51000, 'You do not have access to this project.', 1;
|
|
SELECT @Name=LocationName,@OldParentID=ParentLocationID FROM dbo.Locations WITH (UPDLOCK,HOLDLOCK)
|
|
WHERE LocationID=@LocationID AND ProjectID=@ProjectID AND IsArchived=0;
|
|
SELECT @ParentName=LocationName FROM dbo.Locations WITH (UPDLOCK,HOLDLOCK)
|
|
WHERE LocationID=@ParentLocationID AND ProjectID=@ProjectID AND IsArchived=0;
|
|
IF @Name IS NULL OR @ParentName IS NULL
|
|
THROW 51000, 'Choose active locations from the same project.', 1;
|
|
IF ISNULL(@OldParentID,0)<>ISNULL(@ExpectedParentLocationID,0)
|
|
THROW 51000, 'The parent has changed since this page was loaded. Review the updated tree and try again.', 1;
|
|
IF @OldParentID=@ParentLocationID
|
|
THROW 51000, 'This location already has that parent.', 1;
|
|
DECLARE @AncestorID int=@ParentLocationID;
|
|
DECLARE @Visited TABLE (LocationID int PRIMARY KEY);
|
|
WHILE @AncestorID IS NOT NULL
|
|
BEGIN
|
|
IF @AncestorID=@LocationID OR EXISTS (SELECT 1 FROM @Visited WHERE LocationID=@AncestorID)
|
|
THROW 51000, 'A location cannot be its own parent or be moved beneath one of its descendants.', 1;
|
|
INSERT @Visited VALUES (@AncestorID);
|
|
DECLARE @NextAncestorID int=NULL;
|
|
SELECT @NextAncestorID=ParentLocationID FROM dbo.Locations WITH (UPDLOCK,HOLDLOCK) WHERE LocationID=@AncestorID;
|
|
SET @AncestorID=@NextAncestorID;
|
|
END;
|
|
UPDATE dbo.Locations SET ParentLocationID=@ParentLocationID,UpdatedDate=SYSUTCDATETIME(),
|
|
ModifiedDateUTC=SYSUTCDATETIME(),ModifiedByUserID=@UserID WHERE LocationID=@LocationID;
|
|
DECLARE @Description nvarchar(1000)=CONCAT(N'Parent changed from ',
|
|
COALESCE((SELECT LocationName FROM dbo.Locations WHERE LocationID=@OldParentID),N'top level'),N' to ',@ParentName,N'.');
|
|
EXEC dbo.ProjectAudit_Record @ProjectID=@ProjectID,@UserID=@UserID,@ActivityType=N'Updated',
|
|
@EntityType=N'Location',@EntityID=@LocationID,@EntityName=@Name,@Description=@Description;
|
|
COMMIT TRANSACTION;
|
|
END TRY
|
|
BEGIN CATCH
|
|
IF XACT_STATE()<>0 ROLLBACK TRANSACTION;
|
|
THROW;
|
|
END CATCH;
|
|
END;
|
|
GO
|