0

i am working on a trigger associated with 2 custom objects. when the type__c field (picklist) on role history is updated to a value, the rep_type__c field should automatically take this same value. however, when there is an active role (no end date set) and the user attempts to add another role OF THE SAME TYPE an error should display saying to end date the active role first. this should NOT display if the second role being added is of a different type. below is what i have so far:

trigger RoleHistoryBeforeTrigger on Role_History__c (before insert, before update) {

Map<Id, String> repIds = new Map<Id, String>();  
if(Trigger.isInsert) {
    for(Role_History__c roles :Trigger.New) {
        repIds.put(roles.Rep__c, roles.Type__c);
    }  

    List<Role_History__c> activeRoles = [SELECT Id, Rep__c, Type__c FROM Role_History__c WHERE End_Date__c = NULL AND Rep__c IN :repIds.KeySet()]; 

    Set<Id> setActiveRoleIds = new Set<Id>();        
    for(Role_History__c roles :activeRoles) {
        setActiveRoleIds.add(roles.Rep__c);
    }

    for(Role_History__c roles :Trigger.New) {
        if(setActiveRoleIds.contains(roles.Rep__c) && (roles.Type__c == repIds.get(roles.rep__c))) 
            roles.addError('Please set an End Date on current role before adding a new role.');
    } 
}

right now the errors fires regardless of if the type is the same or not. what am i missing to get this to function properly? i feel like it has to do with the final if statement but don't know what exactly.

thanks

  • Is rep__c unique across all the records? You're using it as the key in the map (repIds), but if there's duplicate keys in a map it just overwrites the value. – Kris Goncalves Oct 3 at 20:17
  • yes, rep__c refers to an Id to the specific rep who's role is being inserted, there will only be 1 rep. the rep object is also the master and the role history object is the child @KrisGoncalves – testing Oct 3 at 21:59
0

Your code is creating a map of Rep__c and Type__c values based on the trigger records...Then you're looping through the Trigger records again and comparing the Type__c values of the trigger record to the map...which is also the trigger records so they'll always be equal and you'll get all errors.

You need to create a map of existing active roles to compare the Type__c value to the records in the trigger.

Map<Id, Role_History__c> activeRoles = new Map<Id,Role_History__c>();
for(Role_History__c rHist : [SELECT Rep__c FROM Role_History__c WHERE End_Date__c = NULL AND Rep__c IN :repIds.KeySet()]){
    activeRoles.put(rHist.Rep__c,rHist);
}

for(Role_History__c roles :Trigger.New) {
        if(activeRoles.containsKey(roles.Rep__c) && (roles.Type__c == activeRoles.get(roles.rep__c).Type__c)) 
            roles.addError('Please set an End Date on current role before adding a new role.');
} 
  • this worked, thank you! question, do i no longer need the setActiveRoleIds set? and if so, could you elaborate on why? – testing Oct 4 at 13:55
  • Well a set is useful to not have any duplicates. The only thing you're doing with that set variable is checking if a Rep__c value is contained in there. It doesn't necessarily matter then if that has duplicates as you just want to see if one exists in there, period. I thought you had mentioned there shouldn't be two role history, active records with the same Rep__c value so there shouldn't be any reason to make sure there's no dupes? – Kris Goncalves Oct 4 at 14:07
  • my requirements had changed since making the set initially. at first, there was only supposed to be 1 single active role on a single rep. now, there can be multiple active roles on a single rep if they are of different types. so i agree i don't think duplicates matter and the set can be removed. thanks for the explanation! – testing Oct 4 at 14:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.