Is there a way to assign a List to a field? - salesforce

I know the question seems weird but hear me out...
Say I have a group of users called Managers.
List userList = [Manager1, Manager2,Manager3,...,ManagerN]
And I wanted to assign one of these managers to a record using a round robin which uses a modulus to determine the count.
integer count = 0;
integer userModulus = Math.round(Math.mod(Count, userList.size()));
count++;
Then use this value to return the index of the list like userList[userModulus] right?
Originally I planned to use custom metadata types to house the lists with the intent of managing these custom metadata lists by screen flow... but on implementation I don't see this being realistic.
Is there a way to store this list of users in a field, or some other kind of structure where it can be maintained by managers or other non-admin users?

There are code-free ways to do it, see https://help.salesforce.com/s/articleView?id=sf.essentials_round_robin_lead_assignment.htm&type=5
Or ready pieces of code you can get inspired with: https://gist.github.com/eskfung/f342b47ecc0849deb0cb
Many ways to achieve this. You could have a field on the User (picklist? checkbox? being assigned a special Role?) and then
List<User> users = [SELECT Id, Name
FROM User
WHERE IsActive = true AND UserRole.Name = 'Sales Manager'
ORDER BY Name];
Bit crude but should get the job done.
You could also add them to a public group or queue? Queues should be pretty close to normal owner assignment functionality anyway. And then you'd query all group/queue members. Queues are a type of group so it'd sit in same table: Group, GroupMember
SELECT Id, Name, Type
FROM Group
WHERE Type IN ('Regular', 'Queue')
SELECT Id, Name
FROM User
WHERE Id IN (SELECT UserOrGroupId FROM GroupMember WHERE Group.Name = 'MyGroup' AND Group.Type = 'Regular')
It's bit simple, it assumes people are directly assigned to the group. In reality groups/queues often consist of other groups, roles, roles+subordinates, not just manually assigned individuals... You'd need to keep querying the GroupMember records till you exhaust the tree.
Still, should be enough to get you started?

Related

Salesforce apex collaborationgroup/collaborationgroupmember relationship?

I'm trying to get a list of collaboration groups and their associated members. I'm trying to do the following soql query but it does not recognise the CollaborationGroup.CollaborationGroupMembers relationship
List<CollaborationGroup> cgs = new List<CollaborationGroup>([Select OwnerId, Id, (select CollaborationGroupMember.MemberId from CollaborationGroup.CollaborationGroupMembers) From CollaborationGroup]);
Looking at the API, CollaborationGroupMembers has a CollaborationGroupId which is the ID of the associated CollaborationGroup, so the relationship should exist - can anyone tell me why it's not working?
Thanks
J
edit: I have figured this out the other way round (going from member to group (child to parent) rather than vice-versa) by doing the following:
List<CollaborationGroupMember> cgs = new List<CollaborationGroupMember>([select MemberId, CollaborationGroupMember.CollaborationGroup.OwnerId from CollaborationGroupMember where CollaborationGroupMember.CollaborationGroup.Name]);
However, I'd still like to know why I couldn't do it from parent to child as I was trying to in the first place?
Thanks
As per the documentation here, it's not having a relation from CollabarationGroup into CollabarationGroupMember. But as you have mentioned, it's having the relation in the otherway around, see this. So if you need to collect members from a particular group you can try
SELECT MemberId FROM CollaborationGroupMember WHERE CollaborationGroupId='your_group_id'
or filter it from CollaborationGroup.Name as you are already doing.

How to query all task which are having relatedto(whatId) as Account or Contact

I am using an soql query to get tasks. My requirement is to get all tasks which are related account or contact object. Also few other fields inside Account or contact object whichever the object related. Is there a simple way instead of writing multiple queries.
Please provide more specific information next time. Generally speaking you can refer to a parent object by reference name followed with a dot. Here is an example
Select Account.Name, AccountId From Task Where Account.Name = 'John'
Here Account is the name of the reference (from task) and AccountId is the referencing field.
Your question is a little unclear. Are you looking for all TASKS related to any ACCOUNT or CONTACT or related to specific ACCOUNTS or CONTACTS?
If the former, try
SELECT Id, Subject,
FROM TASK
WHERE
What.Type = 'Account' OR
Who.Type = 'Contact'
if the latter, use the IN :list syntax already suggested by Moti. The What.Type is useful, as opposed to AccountId!=null, because it will not return TASKS associated with, for example, OPPORTUNITIES (if you want that behavior, use AccountId!=null and maybe drop the Who.Type if you associate all CONTACTS with OPPORTUNITIES, as it would be redundant).
In either case, your issue will be pulling specific data from CONTACT whos, as polymorphic fields only allow access to a limited number of fields. Can't seem to find that list right now. I don't believe old SOQL supports the kind of the syntax to do that in one query--that's why SOQL polymorphism made such a bang--though I could be wrong.
Now, if you have SOQL TYPEOF available to you, you should be able to do something more interesting like:
SELECT Id, Subject,
TYPEOF What
WHEN Account THEN AccountNumber
END,
TYPEOF Who
WHEN Contact THEN FirstName
END
FROM Task
WHERE
What.Type = 'Account' OR
Who.Type = 'Contact'
How about
select {column list] from task where parentid in (select id from account where ...) or parentid in (select id from contact where ...)
Alternatively, if you're inside Apex and already have the contact or account ids in a list (we'll use idList), you can use:
select {column list] from task where parentid in :idList

CakePHP Access Allocation on Role Based specific Data Access

My project requirement is something like this:
On Top, there will be Administrator, who will have all d access, first level
Under Administrator, there will be Department Heads, who will have all d access, apart from Creating Department Heads
Under Department Head, there will Other Members, who will be managing their allocated department wise data.
Now, all different department heads will have their own information and members, and all department heads / Members will have access to their own specific records, which they are entering / managing.
Now, with CakePHP's ACL Component, I can divide the roles and their access level, but all department heads can see the other department head's information, as they will have same level of access, and All Other Members can see the other members information on diff departments, as of they will have same level of access.
My project complexity is that - they should be visible only their assigned or created information / data, though they have same level / role assignments as of others.
Can anyone suggest me best suitable option, to manage all these things with already available plug-ins with CakePHP.
I can work by customizing the default ACL Component, but that will take some more amount of time, than what is expected.
Any better ideas / suggestions would be appreciated !
the way i see it, ACL is not that magical. For exemple: ACL could manage the permissions to tell who has access to add/edit/remove a product.. but it wont be able to change a query to filter the products accordingly to the defined permissions (like "users from department A can only see products from department A").. well actually that's a lie, ACL could manage that but it might not be practical, because every time you add a product you'd have to create an ACO, and set the permission in the AROS_ACOS table and since the AROS is a tree structure, so it could easily become a nigthmare, if your planning to query your data
I'd use a group-only ACL to control the access to certain pages/actions and make rules like:
"Department Head can access the page
'products list' and add/delete/modify
products"
"Administrators can access
all pages"
"Other users can access
'products list' and they can add
products but not delete them"
and i'd adjust my queries accordingly to the connected user, so in the controller of 'products list' page, i'd do something like:
If connected user blongs to Department Head then select all products where product.department_id=connected_user.department_id
If connected user is Admin then select all products
if you have too much queries and you dont want to do thousands of if's sentences, you could create a component, a behavior or maybe extend the find() method in the app_model. The idea is to catch all queries and check if one of the models used on the query have field called "department_id", if they do then add the model.department_id=connected_user.department_id condition to the query.
I did that for one website that can be seen in multiple languages and each language has it's own users, data, logs, etc., and there's one Admin that can see all the info.. and it's working great for me =)
Good Luck!
EDITED:
the behavior i use is:
<?php
class LocalizableBehavior extends ModelBehavior {
/**
* Filter query conditions with the correct `type' field condition.
*/
function beforeFind(&$model, $query)
{
/**
* Condition for the paginators that uses joins
*/
if(isset($query['joins']) && !empty($query['joins'])){
foreach($query['joins'] as $key => $joinTable){
if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
$query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
}
}
}
/**
* condition for the normal find queries
*/
if($model->hasField('lang') && $model->name != "User"){
$query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
}
return $query;
}
}
?>
it's quite simple really, i change the query to add a condition to match to the current language ($_SESSION['lang']). In the controller all i need to do is to attach the LocalizableBehavior and use find method as usual:
$this->Products->find('all');

SOQL query to traverse several levels on Task

I'm trying to write some apex code using this query and not getting anywhere:
List<Task> tasks = [SELECT id, whatid, who.account.parent.name FROM task WHERE who.account.parent.name LIKE 'Procter%'];
I'm not surprised this doesn't work, but can't seem to find documentation anywhere that explains how I would go about this. Does anyone have any idea? I'm trying to get all tasks linked to a contact linked to an account with a parent account of "procter and gamble"...
Looks like the options to "go up" in the mixed fields (the ones where Lookup goes to multiple objects like WhatId going to Account or Opportunity) are very limited. I was able to write "WHERE what.name LIKE 'Procter%' but not "WHERE what.parent.name LIKE 'Procter%'".
By the way I think it should be WhatId and not the WhoId (check out the Validation Rule editor for Tasks, try to insert fields "Contact/Lead ID" and "Opportunity/Account ID"). You will also see that you can't "go up" (or in case of this editor - "go right") on these fields while for some other fields you can explore the relation like for "CreatedBy.UserRole.Name".
Can you try this subquery instead?
[SELECT id, whatid FROM task WHERE whatid IN (SELECT Id FROM Account WHERE Parent.Name LIKE 'United%')]
WhatId and WhoID are polymorphic fields, so these fields do not support traversing multiple levels.
I had a similar requirement for hierarchal traversing, in my case i had to select the lead information associated with a task. What I had to do was first query for a list of tasks, then query for a list of leads based off those tasks, then use a wrapper class to combine the two lists into a custom object and display the object accordingly using visualforce. The wrapper class was certainly my answer to the equation since it seems you are in fact unable to query directly using the Who.Id.
Hope this helps!
The AccountID field on Tasks is populated by SF automatically for Contacts. Obviously, it is blank for Leads. So, if you want to get Account data you can just do something like this:
SELECT ID, Who.FirstName, Who.LastName, Account.Parent.Name FROM Task WHERE WhoID = '00Q12SDFUUALDLKJF'
Obviously, Account.Parent.Name is blank for Leads.

Select distinct users with referrals

I have a bunch of Users. Since Django doesn't really let me extend the default User model, they each have Profiles. The Profiles have a referred_by field (a FK to User). I'm trying to get a list of Users with >= 1 referral. Here's what I've got so far
Profile.objects.filter(referred_by__isnull=False).values_list('referred_by', flat=True)
Which gives me a list of IDs of the users who have referrals... but I need it to be distinct, and I want the User object, not their ID.
Or better yet, it would be nice if it could return the number of referrals a user has.
Any ideas?
Took me a long time to wrap my head around this, but I think I finally got it figured out:
affiliates = User.objects.annotate(num_referrals=Count('referrals')).filter(num_referrals__gt=0)
I didn't think I'd be able to use the reverse relationship
referred_by = models.ForeignKey(User, null=True, blank=True, related_name='referrals')
in Count(), nor did I think you could use the annotated value in the filter... that's pretty cool. I still wish you could use GROUP BY without having to annotate stuff (assuming I didn't need the count).

Resources