0

This is a follow-up question to my previous thread AfterUpdate caused by: System.SObjectException: Field is not writeable EventRelation.RelationId .

Code updates fine for 5 records but when I tried to update 25 records, it keeps older event attendees along with new attendees. It is not properly deleting older event attendees after the update. I know that code is not properly handling bulk records. Don't know how to tweak this so it can handle more records. Thanks.

For example:

Current Attendees: CK, AM, CP

NEW Attendees to update: AA, BB, CC

After Update: CK,AM,CP,AA,BB,CC

But it should be: AA, BB, CC

trigger cloneEventTrigger on Event (after insert, after update) {

if(trigger.isUpdate && cloneEventHelperClass.runOnce) {     
    cloneEventHelperClass.runOnce = false;
   cloneEventHelperClass.onAfterUpdate(trigger.new, trigger.oldmap);
    }     
 }      
}

Helper Class

public class cloneEventHelperClass {
public static boolean runOnce = true;
public static void onAfterUpdate(List<Event> newEvnt, Map<Id, Event>oldMap){  
    // get all ids
    system.debug('After Update cloneEventHelperClass Trigger'); 
    List<Id>eventIds = new List<Id>();
    for(Event evnt : [SELECT Id From Event WHERE id=:newEvnt AND Attendees__c != NULL]){ 
            if (evnt.Id != null){ 
                eventIds.add(evnt.Id);
            }          
        }

    Event[] queryEvent = [
       SELECT Id, Subject, StartDateTime, EndDateTime, OwnerId, Whoid, Whatid,Description,Location, Reason_for_Call_Meeting__c,
        Attendees__c  From Event WHERE id=:eventIds];
        Map<String, Id> initialsToUserId = new Map<String, Id>();
        Set<String> initials = new Set<String>();
        Map<id,User> updateAll= new Map<id, User>();

 // loop through query and add all initials to set 
   for(Event record: queryEvent) {
        initials.addAll(record.Attendees__c.split(';'));
    }

// Pull old initials
    List<String>splitList;
    for(Event evnt : [SELECT Id,Attendees__c From Event WHERE id=:eventIds]){
         if (evnt.Attendees__c != null)
        {

            system.debug('oldEven: ' + oldMap.get(evnt.Id).Attendees__c);
            String multiValues = oldMap.get(evnt.Id).Attendees__c;
            splitList= multiValues.split(';');

        }
    }  

//Remove all existing EventRelation ID if new and old attendees are not same
system.debug('initials:' + initials+'initials size:'+initials.size());
system.debug('splitlist'+ splitList.size());
    If(splitList.size() != initials.size()) {

    System.debug('they are not the same attendees'+ splitList + 'AND '+ initials);
    If(!eventIds.isempty()){
               Map<Id, EventRelation> relations = new Map<Id, EventRelation>([select id from EventRelation where EventId IN: eventIds]);
               System.debug('Size of relation before deletion' + relations.size());
                 If(!relations.isempty()){  
                      delete relations.values();
                 }

               } 


// query for user and their initials and add them to Map. 
    for(User record: [SELECT Id, Initials__c FROM User WHERE Initials__c = :initials AND IsActive = TRUE]) {
      initialsToUserId.put(record.Initials__c, record.Id);
    }
        //Added Debug Statement
        system.debug('@@@initialsToUserId'+initialsToUserId);

// loop through same Event Query to fetch all fields and check all the initial with Id against set. T 

    list <EventRelation> relationsIns = new list <EventRelation>();
    list < Event> eventlist = new list<Event>();

    for(Event record: queryEvent) {
        system.debug('@@@CameIN@@@1');
        record.WhatId = oldMap.get(record.Id).whatId;
        system.debug('@@@record.WhatId '+ record.WhatId);
        eventlist.add(record);
        EventRelation parentRelation = new EventRelation();
             parentRelation.EventId= record.Id;
             parentRelation.RelationId = record.WhatId;
             parentRelation.isWhat = true;
             parentRelation.isParent = true;
             parentRelation.isInvitee = false;
        relationsINS.add(parentRelation);  
        for(String initial: record.Attendees__c.split(';')) {
            system.debug('@@@CameIN@@@2');
            Id attendeeId = initialsToUserId.get(initial);
            system.debug('@@@'+attendeeId +'@@@initials'+initial);
            if(attendeeId != null && record.OwnerId != attendeeId) {
             system.debug('@@@CameIN@@@3');

             EventRelation e = new EventRelation();
             e.EventId= record.Id;
             e.RelationId = attendeeId;
             relationsINS.add(e);  

          }    
        }
      }// end of query
        system.debug('Trigger Ran FINE!!!!!'); 
        system.debug('relations To Insert: '+relationsINS); 
        list <EventRelation> relations1 =[select id from EventRelation where EventId IN: eventIds];
        System.debug('Size of relation after deletion' + relations1.size());
        //Database.insert(relationsINS,false);
        //update eventlist;

        insert relationsINS; 

      } // End of IF Statement
    } //End of onAfterInsert Trigger
}
6
  • From your code, it appears to me as though you're trying to combine multiple events before you begin to get eventrelationIds. This looks problematic to me. Also, I'd be wary of creating maps based on names instead of eventrelationId's or contactId's (your whoId). – crmprogdev Apr 25 '20 at 16:03
  • Thanks. What do you mean by "wary of creating maps based names instead of eventrelationId" – mike Apr 30 '20 at 17:17
  • Ids generally are unique. Text values may not always be unique. This can result in a situation where you attempt to relate two unique ids in a map as values to the same text key. It could also be a situation where you have non-unique text values entered with a common id values if you have duplicate issues. It all depends on how you plan to use your map. Only one entry would be expected to resolve for a value set when a non-unique Id is saved with a unique text key, yet the opposite would occur with unique keys and non-unique text values. Is confusing, I know. – crmprogdev May 1 '20 at 15:19
  • Thank you. Now going back to your original comment, how do I not combine multiple events? I am not even sure how I can make sure that eventrelationId gets deleted for each event that is getting updated. Another issue I encountered is when I deleted all eventrelationIds for evenId ..it removes the whatID and for that reason, I had to write extra code in the for loop. – mike May 1 '20 at 15:39
  • I'm not inclined to rewrite your entire trigger for you. It sounds like you've not created enough of the right maps. From what you're sharing, you probably need maps of EventIdToEventName (assumes all Events are named the same), WhatIdToEventId, EventNameToEventRelationId, and/or the reverse of these in addition to what you already have (EventRelationIdToContactName, etc.). This type of problem is usually about creating enough of the right maps or the equivalent from your queries. – crmprogdev May 3 '20 at 14:02

Your Answer

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

Browse other questions tagged or ask your own question.