Microsoft CRM中配製總公司和分公司架構中遇到問題的解決(一)

   本項目中,客戶有明顯的總公司和分公司的切分。

要求:

1)各分公司間的數據隔離

2)總公司可以看到分公司的數據

CRM中的權限結合組織架構,可以很方便實現這種安全級隔離。我們將組織架構設置成,根節點,爲總公司。然後在總公司下分別建各分公司的節點。

總公司用戶掛在根節點上,而分公司用戶分別掛在分公司的子節點上。

但是也要看到,也會帶來一些預想之外的工作。下面一一道來

1.CRM的 角色會自動繼承到各節點上,導致在上述的結構中存在一個矛盾的地方。

    CRM中有一個系統管理員的角色,是誰都不能動的,這個角色也會自動繼承到每個節點上。而分公司必定會設置一個系統管理員來打理分公司內的系統上的設置事務(分公司系統管理員要具備可以設置用戶安全角色的權限),這就有一個現成的後門,即分公司系統管理員可以把自己設置成這個系統中固定的系統管理員角色,從而獲得了最高經級的權限,就可以看到其他分公司甚至總公司的數據。

    把角色設置權限全部收到總部,這也不現實,分公司的日常事務要總公司的系統管理員來做,也是繁瑣不已。

   CRM的安全架構就是和一個樹型組織結構緊密結合,所以只能用些unsupported的定製方法了。

  首先,讓我們整理出規則就是:

 1)要阻止根節點的安全角色不能繼承到各子節點。

      對策:CRM會根據組織架構自動插入多條角色記錄,考慮在表RoleBase上建Trigger,將這些繼承的記錄都打上刪除標記(deletionstatecode=1)

2)而非根節點的安全角色可以繼承到其的子節點下

   對策:要能檢索出當前角色是不是從根節點的安全角色中繼承下來的。

接下來就可以開始行動了,自然要先解決如何判斷出當前的角色是不是從根節點繼承下來的問題。組織架構的遍歷檢索自然就是一個遞歸查找的問題。SQL 2005的CTE技術可以派上用處了。

先建立一個函數,判斷是否是從根節點上繼承下來的。

USE [OCS_MSCRM]
GO
/****** 對象:  UserDefinedFunction [dbo].[fn_IsRootHirachyRole]    腳本日期: 04/01/2007 19:24:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <Author,,wengyan>
-- Create date: <Create Date, ,2007/07/02>
-- Description: <Description, ,identify if the role is inherit from root unit>
-- =============================================
CREATE FUNCTION [dbo].[fn_IsRootHirachyRole]
(
 -- Add the parameters for the function here
 @roleid uniqueidentifier
)
RETURNS int
AS
BEGIN
 -- Declare the return variable here
 declare @cnt int;

 -- Add the T-SQL statements to compute the return value here
 with rolehirachy(roleid,name,ParentRoleId,level)
    as
 (
  select roleid,name,ParentRoleId,0 as level from rolebase
  where roleid=@roleid
  union all
  select d.roleid,d.name,d.ParentRoleId,level+1
  from rolehirachy e inner join
  rolebase d on
  d.roleid=e.ParentRoleId
 )

 select @cnt=count(1)
 from rolehirachy e
 inner join rolebase c
 on e.roleid=c.roleid
 inner join businessunitbase d
 on c.businessunitid=d.businessunitid
 where e.parentroleid is null and d.parentbusinessunitid is null

 -- Return the result of the function
 RETURN @cnt

END

然後就是寫一個insert時候的trigger,這簡直就是小菜一碟了。

-- ================================================
-- Template generated from Template Explorer using:
-- Create Trigger (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- See additional Create Trigger templates for more
-- examples of different Trigger statements.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <Author,,wengyan>
-- Create date: <Create Date,,2007/07/02>
-- Description: <Description,,
--               當創建角色時,從根節點繼承下來的角色設置刪除標記=1>
-- =============================================
CREATE TRIGGER tg_set_deletionstatecode_on_insert
   ON rolebase
   AFTER INSERT
AS
BEGIN
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;

    -- Insert statements for trigger here
 update role set deletionstatecode=1
    where dbo.fn_IsRootHirachyRole(roleid)=1 and ParentRoleId is not null
END
GO

經過測試,一切OK。

這個問題的解決要了解CRM的特點,然後加上一定的數據庫功底即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章