0

I have written an trigger for update application object based on new created record. In update logic its working but I am getting error on insert logic.

Apex trigger AppLeadCreation caused an unexpected exception, contact your administrator: AppLeadCreation: execution of AfterInsert caused by: System.FinalException: Record is read-only: Trigger.AppLeadCreation: line 68, column 1

Please check the below code and suggest me what's wrong with this?

trigger AppLeadCreation on alu_Application__c (after insert,before update){

    // SOQL QUERY FOR ITERATES
    private static List<Lead> leadsList= new List<Lead>();
    private static Set<String> appEmails = new Set<String>();


    // MAP OF IDs AND EMAIL ADDRESS OF LEAD
    private static  Map<String,Id> mapIdsWithLeadEmail = new Map<String,Id>();

    // MAP OF IDs AND EMAIL ADDRESS OF APPLICATION
    Map<Id,String> mapIdsWithAppEmail = new Map<Id,String>();

    // MAP OF LEAD IDs AND APPLICATION ID
    Map<Id,Id> mapAppIdsEmailIds = new Map<Id,Id>();

    Map<Id,Lead> mapAppIdwithLeads = new Map<Id,Lead>();

    Map<Id,Lead> leadsToCreate = new Map<Id,Lead>();

    Map<Id,Lead> leadtoUpdate = new Map<Id,Lead>();     

    Map<Id,alu_Application__c> apptoUpdate = new Map<Id,alu_Application__c>(); 
   // to prevent the recursion  
    public static boolean isRecursive=true;
    System.debug('mapIdsWithLeadEmail'+mapIdsWithLeadEmail);

    for(alu_Application__c app : trigger.new){
        if(String.isNotBlank(app.Email__c)){
           mapIdsWithAppEmail.put(app.Id,app.Email__c);
           appEmails.add(app.Email__c);
         }
    }
    System.debug('mapIdsWithAppEmail'+mapIdsWithAppEmail);
    try {
           if(!mapIdsWithAppEmail.isEmpty() && isRecursive){
               isRecursive = false;
              // fetch leads information based on Application Email
              leadsList =[SELECT Id, Email FROM Lead WHERE Email IN: appEmails];
              if(!leadsList.isEmpty()){
                 for(Lead le : leadsList){       
                   mapIdsWithLeadEmail.put(le.email, le.Id);
              }
             } 

            for(Id tmp : mapIdsWithAppEmail.KeySet()){
                String appEmail = mapIdsWithAppEmail.get(tmp);
               if(mapIdsWithLeadEmail.ContainsKey(appEmail)){ 
                   mapAppIdsEmailIds.put(tmp,mapIdsWithLeadEmail.get(appEmail));
               }else{
                    leadsToCreate.put(tmp,leadInfo(trigger.newMap.get(tmp),'insert',null));
               }
              }
            }
        System.debug('mapAppIdsEmailIds'+mapAppIdsEmailIds);
        System.debug('leadsToCreate'+leadsToCreate);

        if(!mapAppIdsEmailIds.isEmpty() || !leadsToCreate.isEmpty()){
            //insert the new leads for unmathced application EMAIL
            Database.insert(leadsToCreate.values());

            for(alu_Application__c app : trigger.new){
                if(mapAppIdsEmailIds.ContainsKey(app.Id)){
                    app.Lead__c = mapAppIdsEmailIds.get(app.Id);
                    leadtoUpdate.put(app.Id, leadInfo(app,'update',app.Lead__c));
                }               
                else if(leadsToCreate.containsKey(app.Id)){
                    **app.Lead__c = leadsToCreate.get(app.Id).Id;**
                }
                if(Trigger.isAfter && Trigger.isInsert && app.Lead__c != NULL){
                    apptoUpdate.put(app.Id,app);
                }
            }
            if(!leadtoUpdate.isEmpty()){
                update leadtoUpdate.values();
            }
            if(!apptoUpdate.isEmpty()){
                update apptoUpdate.values();
            }
         }     
        }Catch(Exception e){
        System.debug('ERROR:' + e.getMessage());
        System.debug('ERROR:' + e.getLineNumber());
      }

     private static Lead leadInfo(alu_Application__c app, String eventType, Id LeadId){
         Lead leadtoSend = new Lead();
         if(eventType.equals('update')){
             leadtoSend.Id = LeadId;
         }
         leadtoSend.FirstName = app.First_Name__c;
         leadtoSend.LastName = app.Last_Name__c;
         leadtoSend.Email = app.Email__c;
         leadtoSend.Campus_Preference__c = app.Campus_Preference__c; 
         leadtoSend.Company = app.First_Parent_Company__c;


        return leadtoSend;
     }

}

1 Answer 1

0

You can't attempt to modify any fields in a record on Trigger.new. At minimum, it looks like you'll need to change this:

        if(!mapAppIdsEmailIds.isEmpty() || !leadsToCreate.isEmpty()){
            //insert the new leads for unmathced application EMAIL
            Database.insert(leadsToCreate.values());

            for(alu_Application__c record: trigger.new){
                // Temp record to use for update
                alu_Application__c app;
                if(mapAppIdsEmailIds.ContainsKey(record.Id)){
                    if(Trigger.isBefore) {
                        record.Lead__c = mapAppIdsEmailIds.get(record.Id);
                    } else {
                        // Clone record and update
                        app = record.clone(true);
                        app.Lead__c = mapAppIdsEmailIds.get(app.Id);
                    }
                    leadtoUpdate.put(record.Id, leadInfo(record,'update',app.Lead__c));
                }
                else if(leadsToCreate.containsKey(record.Id)){
                    if(Trigger.isBefore) {
                        record.Lead__c = leadsToCreate.get(record.Id).Id;
                    } else {
                        // Clone record and update
                        app = record.clone(true);
                        app.Lead__c = leadsToCreate.get(record.Id).Id;
                    }
                }
                if(app != null) {
                    appToUpdate.put(app.Id, app);
                }
            }
            update leadtoUpdate.values();
            update apptoUpdate.values();
         }

You could probably optimize your code some more (I took out some extraneous "if" statements, for example).

2
  • Thanks @sfdcfox, I have made the changes, now its only working for insert logic not for update.
    – Maggie
    Sep 28, 2017 at 7:42
  • 1
    @Maggie I believe you've made your code overly complicated, so I didn't dig too far into this, but you might have an easier time of it if you simply called your recursive call on insert immediately and allow the before update logic to do all the heavy lifting. Something like this: trigger X on Y (after insert, before update) { if(Trigger.isInsert) { update trigger.new.deepclone(true); } else { /* create or update leads here */ }. It'd be a pretty major rewrite, though, but would simplify the overall logic.
    – sfdcfox
    Sep 28, 2017 at 7:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .