本文由 Gideon(AI)翻译自英文原版。
我到目前为止已经大约 36 个小时没有睡觉了,请多包涵。
以下解决方案受到了 这篇文章的启发。
使用场景 链接到标题
用户希望能够自动将用户动态分配到队列,同时希望在满足条件时,根据商机所有者所在部门,动态将商机提交给相关队列进行审批。
拆解问题 链接到标题
我从算法学习中学到的一件事,就是拆解问题,分而治之。
在我们的使用场景中,主要有 2 个问题:
- 动态将用户分配到队列
- 动态将商机提交给队列
一旦将问题拆解成这两个部分,解决方案就清晰了。
- 动态将用户分配到队列:使用触发器动态添加/移除用户
- 动态将商机提交给队列:使用流程在满足特定条件时提交审批
动手实践 链接到标题
我们需要:
- 自定义对象:审批矩阵(Approval Matrix)
- 用于映射商机记录与应提交至哪个队列
- 将该对象的"所有者"字段作为审批人,这将帮助我们解决 2 个问题:
- 商机队列(此功能将在 2022 年版本中推出,如果我没记错的话)
- 查找至队列的自定义字段不存在
- 审批流程
- 流程触发器:在创建商机记录时创建"审批矩阵"记录,在商机更新时更新"审批矩阵"记录所有者(使用触发器代码可能比流程更简单)
- 流程触发器:在满足特定条件时提交审批;在本例中,我做了简化,当商机阶段 = “需求分析"时,自动提交审批
- 自定义元数据类型:我仅用它来映射部门和队列名称,但你可以添加更复杂的条件,例如,如果用户属于某个特定客户,则应被分配到特定队列。你也可以将这类逻辑放在这里。
- 用户触发器:将用户添加/移除到适当的队列(也可以使用流程,只是对我来说,触发器更容易操作,有时候我就是不想拖拖拽拽……)
请注意,我的流程完全没有做批量化处理……你应该始终这样做,我只是需要一个概念验证。
自定义对象 链接到标题
这只是一个简单的记录,用于映射商机和审批人队列
注意这里的"所有者"字段,它将作为审批人使用。在我的流程中,当新的商机记录创建时,审批矩阵记录的所有者字段会自动分配给"空队列”(一个没有任何用户的队列)。在实际操作中,你应该优化此流程,自动分配到正确的队列,除非找不到合适的队列。我这里只是偷了个懒。
审批流程 链接到标题
你的审批流程设置如下
审批流程
注意"指定审批人"设置为"相关用户:所有者"
邮件模板将是一个 VF 邮件模板,你可以在其中查询相关记录
邮件模板示例
流程触发器:创建"审批矩阵"记录 链接到标题
我构建的流程截图
正如我之前所说,你应该优化以下内容:
- 批量化处理
- 创建记录时也设置队列 –> 这将改善用户体验
流程触发器:提交审批 链接到标题
当阶段变更为"需求分析"时,将提交审批
流程截图
- 用户触发器:
自定义元数据类型 链接到标题
以下是我的自定义元数据类型设置
自定义元数据类型设置
至少在我的场景中,我们只需要在这里映射部门和队列。你可以根据需要做得更复杂。例如,如果用户属于某个特定客户,则应被分配到特定队列,你也可以在这里添加这类逻辑。
以下是记录示例:
自定义元数据类型记录示例
用户触发器 链接到标题
将用户添加/移除到适当的队列(也可以使用流程,只是对我来说,触发器更容易操作,有时候我就是不想拖拖拽拽……)
以下是我的代码:
触发器
trigger UserTrigger on User (after insert, after update, before insert, before update) {
if(trigger.isBefore && (trigger.isUpdate || trigger.isInsert) ) {
UserTriggerHandler.addUserToQueue(Trigger.New,Trigger.Old);
}
}
处理器
public class UserTriggerHandler {
public static void addUserToQueue(List<User> TriggerNew, List<User> TriggerOld) {
map<String, String> manager_dep_map = new map<String, String>();
set<String> keySet_dep = new set<String>();
list<GroupMember> gmLists = new list<GroupMember>();
List<String> depNames = new List<String>();
for(User_Assignment_Queue__mdt cmdt_User :[select Id,Queue__c, Department__c
from User_Assignment_Queue__mdt
]){
manager_dep_map.put(cmdt_User.Department__c, cmdt_User.Queue__c);
}
for(User usrO : TriggerOld){
removeUserHelper(usrO);
}
system.debug('depNames = '+depNames);
for(User usr: TriggerNew){
if(usr.Manager__c && usr.Department <> NULL) {
if(manager_dep_map.get(usr.Department) <> NULL){
Id qId = [select Id from Group where Type =: 'Queue' AND Name =: manager_dep_map.get(usr.Department) ].Id;
GroupMember gm = new GroupMember(GroupId = qId, UserOrGroupId = usr.Id);
gmLists.add(gm);
}
else{
Group g = new Group(Type='Queue',
Name = usr.Department + 'Team Queue');
insert g;
GroupMember gm = new GroupMember(GroupId = g.Id, UserOrGroupId = usr.Id);
gmLists.add(gm);
usr.addError('This is a new department, please setup the queue and conditions accordingly');
}
}
}
system.debug('gmLists = '+ gmLists);
depNames.clear();
insert gmLists;
}
public static void removeUserHelper(User UserOld){
list<GroupMember> DeleteGroupMemberRecord = New list<GroupMember>();
list<Id> qId = new list<Id>();
list<Id> oldUId = new list<Id>();
List<String> depNames = new List<String>();
map<String, String> manager_dep_map = new map<String, String>();
for(User_Assignment_Queue__mdt cmdt_User :[select Id,Queue__c, Department__c
from User_Assignment_Queue__mdt
]){
manager_dep_map.put(cmdt_User.Department__c, cmdt_User.Queue__c);
}
String groupName = manager_dep_map.get(UserOld.Department);
system.debug('groupName = '+groupName);
if(UserOld.Manager__c){
for(GroupMember gm:[
select Id, Group.Name, UserOrGroupId from GroupMember where UserOrGroupId =: UserOld.Id AND Group.Name =: groupName
]) {
DeleteGroupMemberRecord.add(gm);
}
}
else{
for(GroupMember gm:[
select Id, Group.Name, UserOrGroupId from GroupMember where UserOrGroupId =: UserOld.Id
]) {
DeleteGroupMemberRecord.add(gm);
}
}
System.debug('DeleteGroupMemberRecord = '+DeleteGroupMemberRecord);
if(!DeleteGroupMemberRecord.isEmpty()) {
delete DeleteGroupMemberRecord;
}
}
}
关于队列设置的完整说明:
队列
见证真相的时刻! 链接到标题
首先测试用户部分
我们有这个用户 John Doe,我添加了另一个名为"Manager"(经理)的复选框字段,原因是在这个使用场景中,一个部门有多个经理。这样就解决了一个用户只能有 1 个经理的问题,因为在这个使用场景中,可以有多个经理。(我知道,有点奇怪)
在用户记录上,根据需要设置部门字段,在我的案例中,我将其设置为"Sales"并勾选经理复选框,保存后你会看到该用户已被分配到一个队列。
John Doe
经理复选框
成功分配队列
创建一个新商机,同时应该会创建一条新的审批矩阵记录
新商机
审批矩阵记录已创建
现在我将商机阶段更新为"需求分析"
阶段已更新
现在如果你导航回审批矩阵记录,你应该看到所有者已相应更新为"销售团队队列"
审批矩阵已更新
如果你进入"相关"选项卡,你应该看到一个审批流程已提交给队列(此记录的所有者)
审批已提交
成功了!!!!!
结论 链接到标题
根据你自己的业务流程,这里的逻辑可能会变得非常复杂。
一旦把问题拆解开来,事情就会在某种程度上变得更清晰、更简单。
好了,我现在已经连续工作了整整 44 个小时。我要去补个觉了。
如有任何问题请告诉我,我也欢迎大家的反馈。谢谢!!














