Find your content:

Search form

You are here

Trigger - Collection - List Question

 
Share

I'm working on this trigger:

trigger ActivityCostInvitees on Event (after update){

    List<EventRelation> whoRelations = [SELECT Id, Relation.Name, Status
                                          FROM EventRelation
                                         WHERE Event.Status_Event__c ='Completed' 
                                           AND EventId IN: Trigger.old];

    List<Id> userId = new List<Id>();

    if(Trigger.isAfter){
        if(Trigger.isUpdate){

            for(Integer i=0; i<whoRelations.size(); i++) {
                if(!whoRelations.IsEmpty()){
                    userId.add(whoRelations[i].Relationid);
                }else {
                    System.assert(false);
                }
            }

            List<User> finalUsers = [SELECT Id, Name, Title, Country 
                                       FROM User 
                                      WHERE Id IN : userId];
        }
    }
}

Now, let's say that the 'finalUsers' contains two users. These users have different titles and are from different countries. I want to first know the Country of each of the users and the Title of each user. Based on that I will do some further calculations. Anyone?Thanks in advanced!

14-05-2014

Thank you for your replies. I think that maybe I was not clear enough on my question. Apologies :( ... I will try to put it on a different way.

I have make some modifications. I added the Rate__c amount field on the User detail page. The field Rate__c is just a formula that will assign a correct amount to the user by looking the Country and the Title. So that is great because I can save some code in my trigger. Now, the question is how do I sum the amount for each of the users inside the finalUsers list?

If I have 3 users in the finalUsers list how can I access each Rate__c for each user and sum the to get a total rate amount?

Any ideas?


Attribution to: Carlos Naranjo

Possible Suggestion/Solution #1

I think I got it.

We have the finalUsers list:

List<User> finalUsers = [SELECT Id, Name, Title, Country, Activity_Rate__c FROM User WHERE Id IN : userId];

So after adding the Rate__c field on the user detail page I can get those values from the user list finalUsers. This is from the developer console. What I do is:

`for(User u: finalUsers){
    if(u.Country != 'US'){ //US use combinations between Title and Country to get different rate. 

    Decimal userRate;
    Integer userSize;
    Decimal totalRate;

    userSize = finalUsers.size();
    userRate = finalUsers[0].Activity_Rate__c;
    totalRate = userRate * userSize;

    System.debug('This is the user rate: ' + userRate);
    System.debug('The total rate that is number of users multiply for user rate is :' + totalRate);
    }

}`

I use the u.country != 'US' because in our requirements US users are using a different logic. All others are using the same rate in relation to their country. Because the finalUsers, at this point, will never be empty I can use the line userRate = finalUsers[0].Activity_Rate__c;. On those countries with equal Rate__c for their users this will be easy. Like I said at this stage if we reach the finalUser and the Country is not US, we will have at least one user in our finalUser list. This will stop getting any "list out of bounds error".

For US users then all I did was this, (Developer Console):

 List<User> territoryManagerUS = [SELECT Id, Country, Title, Activity_Rate__c 
                                  FROM User 
                                  WHERE Title ='Territory Manager' 
                                  AND Id IN : finalUsers];
 if(!territoryManagerUS.isEmpty()){

     Decimal userRateTM;
     Integer userSizeTM;
     Decimal totalRateTM;    

     userSizeTM = territoryManagerUS.size();
     userRateTM = 12.50;
     totalRateTM = userRateTM * userSizeTM;

System.debug('The number of user with title Territory Manager are: ' + territoryManagerUS.size());
System.debug('TM amount of users is ' + territoryManagerUS.size() + 'and the total rate for TM is: ' + totalRateTM); 
 }

So by doing this I can separate them and build my calculations between groups. In my requirements we have a small group of US titles, 5 in total, so it will be ok to use this approach.

Please, if anyone have any comments let me know. Regards and thanks.


Attribution to: Carlos Naranjo

Possible Suggestion/Solution #2

Just FYI, this should be changed:

if(Trigger.isAfter){
        if(Trigger.isUpdate){
        for(Integer i=0; i<whoRelations.size(); i++) {
            if(!whoRelations.IsEmpty()){
                userId.add(whoRelations[i].Relationid);
            }else {
                System.assert(false);
            }
        }

        List<User> finalUsers = [SELECT Id, Name, Title, Country 
                                   FROM User 
                                  WHERE Id IN : userId];
    }
}

to

if(Trigger.isAfter && Trigger.isUpdate)
{
  for (EventRelation relation: whoRelations)
  {
    userId.add(relation.RelationId);
  }

  List<User> finalUsers = [SELECT Name, Title, Activity_Rate__c, Country FROM User WHERE Id IN :userId];
  Integer userSize = finalUsers.size();
  Decimal totalRate = 0;
  for (User curr: finalUsers)
  {
    Decimal userRate;

    if (curr.Country != 'US')
    {
      userRate = curr.Activity_Rate__c
    } else if (curr.Title == 'Territory Manager')
    {
      userRate = 12.50;
    } else if (curr.Title == 'Some other title')
    {
      userRate = someOtherVal;//Fill in the blanks here
    }

    totalRate += userRate;
  }
  //After your loop, totalRate will have the correct value between all of the users
}

EDIT: You could still potentially run into issues if multiple events are being updated at the same time. It could throw off data and you might need to use a Map to switch between the associations.


Attribution to: dphil

Possible Suggestion/Solution #3

Does this answer your question?

for(User usr: finalUsers)
{
    if(usr.Country=='China')
        dosomething();
    if(usr.Title=='SomeTitle')
        dosomethingelse();
}

Attribution to: PepeFloyd

Possible Suggestion/Solution #4

Try this. It may-or-may not wor as it was wrote in Notepad++ :)

trigger ActivityCostInvitees on Event (after update){
    if(Trigger.isAfter && Trigger.isUpdate){
        List<EventRelation> whoRelations = [SELECT  RelationId 
                                            FROM    EventRelation
                                            WHERE   Event.Status_Event__c ='Completed' 
                                                    AND  EventId IN: Trigger.old];
        if(whoRelations.IsEmpty()){
            return; // I don't understand why you use Assert so I replaced it
        }

        Set<Id> userIds = new Set<Id>();

        for(EventRelation er : whoRelations){
                userIds.add(er.Relationid);
        }

        if(userIds.isEmpty()){
            return;
        }
        List<User> users = MyClass.methodThatDoesSomething([SELECT Id, Name, Title, Country FROM User WHERE Id IN : userIds]);
        update users;
    }
}

and class

public class MyClass{
    public static User methodThatDoesSomething(User[] users){
        for(User usr : users){
            if(usr.Country == 'something'){
                if(usr.Title == 'somethingElse'){
                    /** do Something **/
                }
            }
        }
    }
}

EDIT: One thing you might want to keep in mind, that if there are multiple Events going on here, it will tally up the value for ALL events. You would need to add additional logic for that.


Attribution to: Artur Kępczyński
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/34981

My Block Status

My Block Content