Apex共有で所有者と同じロールへレコードを共有する方法
Salesforceでは、組織の共有設定が「非公開」に設定されている場合、
同じロールに属するユーザが所有するレコードは参照できません。
(営業部ロールにAさんとBさんが属していた場合、Aさんが所有するレコードをBさんは参照できない)
一方で、「同じロールに属するユーザが所有するレコードは参照できるようにしたい
(営業部の誰かが所有するレコードは、営業部全員で参照できるようにしたい)」
という要望を頂くことは結構多いような気がします。
この要望は、↓の共有ルールを作成すれば実現できます。
所有者の所属:「営業部ロール」
共有先:「営業部ロール」
アクセス権:「参照のみ」
但し、この方法だと、このルールを適用するロールの数だけ共有ルールを作成しなければなりません。また、ロールの追加や変更の度に、共有ルールを追加・変更しなければなりません。
大規模な組織などで、ロールの数が多い場合や、ロールの追加・変更が多い場合は、
下記で紹介する方法で、トリガからApex共有を使って、自動的に対応するロールにレコードを共有すると良いでしょう。
トリガでApex共有を使って、レコード共有する方法
1. トリガを作成するオブジェクトに、Apex共有の理由を作成
理由表示ラベルと理由名を設定(どちらも任意の名称でOK)して、Apex共有の理由を作成します。
ここでは、
理由表示ラベル:所有者のロールへの共有
理由名:OwnerRoleSharingReason
と設定します。
2. トリガ作成
オブジェクトに所有者のロールへレコードを共有するトリガを作成します。
ここでは、Item__cというカスタムオブジェクトに作成する場合のソースコードを記載します。
Trigger ShareItemTrigger on Item__c (after insert, after update) { // レコードIDリストの作成 // 所有者IDリストの作成 List<ID> recordIdList = new List<ID>(); List<ID> ownerIdList = new List<ID>(); for(Item__c item : Trigger.new){ recordIdList.add(item.Id); ownerIdList.add(item.OwnerId); } // 共有レコード追加リストの作成の // 共有先ユーザ/グループの設定のところで、 // 所有者IDに対応するグループIDを取得したいので、 // 「所有者ID-ロールID マップ」と // 「ロールID-グループID マップ」を作成する // // 所有者ID-ロールID マップの作成 Map<Id, Id> ownerIdMap = new Map<Id, Id>(); for(User u : [Select Id, UserRoleId From User Where Id = :ownerIdList]) { ownerIdMap.put(u.Id, u.UserRoleId); } // ロールID-グループID マップの作成 Map<Id, Id> roleIdMap = new Map<Id, Id>(); for(Group grp : [Select Id, RelatedId From Group Where RelatedId = :ownerIdMap.values() and Type = 'Role']) { roleIdMap.put(grp.RelatedId, grp.Id); } // 共有レコード追加リストの作成 // (共有オブジェクトに追加するレコードを作成する) List<Item__Share> addShareList = new List<Item__Share>(); for(Item__c item : Trigger.new) { Item__Share shareObj = new Item__Share(); // 共有レコードID shareObj.ParentId = item.Id; // 共有先ユーザ/グループ // (所有者のロールに対応するグループIDを設定) shareObj.UserOrGroupId = roleIdMap.get(ownerIdMap.get(item.OwnerId)); // アクセス権限 // 参照のみ : read // 参照・更新 : edit shareObj.AccessLevel = 'read'; // 共有の理由 shareObj.RowCause = Schema.Item__Share.RowCause.OwnerRoleSharingReason__c; addShareList.add(shareObj); } // 共有レコード削除リストの作成 List<Item__Share> delShareList = [Select Id From Item__Share Where ParentId = :recordIdList and RowCause = :Schema.Item__Share.RowCause.OwnerRoleSharingReason__c]; try { // 共有の理由が「所有者のロールへの共有」である // 共有レコードを削除してから、追加する delete delShareList; insert addShareList; } catch(System.DmlException e) { } }
トリガ作成後に、レコードを追加・更新すると、所有者のロールにレコードが共有されるようになります。
レコードの詳細画面で「共有」を押下すると、↓のように、所有者のロールへ共有されていることが分かります。
コメント