function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Integration 39Integration 39 

Update opportunity field when won

Hello,
I have got a trigger the insert into custom object when opportunity is won.

The problem i am having is if someone update the opportunity after it is won another record is inserted into the custom object.

To avoid this i tried adding a custom field to specify if this is the first time it has been updated when the opportunity has been won.

I am getting a front end error saying the opportunity is readonly, how can i fix this?

trigger CreateEnrolment on Opportunity (After update) {

    List<enrolment__c> createenrolment = new List <enrolment__c> ();
    
    for (Opportunity o: trigger.new) {
            if (o.isWon == true && o.converted_2_enrolment__c == FALSE) {
                    createenrolment.add(
                    new enrolment__c(
                    Campaign_Medium__c = o.Campaign_Medium__c,
                    Campaign_Name__c = o.Campaign_Name__c,
                    Product__c = o.Product__c,
                    Opportunity__c = o.id,
                    Account__c = o.AccountId,
                    Call_Centre__c = o.Call_Centre__c,
                    Who_Enrolled__c = UserInfo.getUserId()));
                    
                    o.converted_2_enrolment__c = TRUE;
                    update o;
            }
    }

    try {
        insert createenrolment;
    }
    catch (Exception Ex){
        system.debug(Ex);
    }
}
 
Best Answer chosen by Integration 39
Integration 39Integration 39
I ended up using OpportunityLineItem to get around the problem

trigger CreateEnrolment on Opportunity (after update) {

    List<enrolment__c> createenrolment = new List <enrolment__c> ();
    
    for (Opportunity o: trigger.new) {
            if (o.isWon == true && o.HasOpportunityLineItem == true) {
                String opptyId = o.Id;
            
                OpportunityLineItem[] OLI = [Select id,converted_2_enrolment__c From OpportunityLineItem where OpportunityId = :opptyId];
                for(OpportunityLineItem ol: OLI){
                    if (ol.converted_2_enrolment__c == FALSE) {
                        createenrolment.add(
                        new enrolment__c(
                        Campaign_Medium__c = o.Campaign_Medium__c,
                        Campaign_Name__c = o.Campaign_Name__c,
                        Product__c = o.Product__c,
                        Opportunity__c = o.id,
                        Account__c = o.AccountId,
                        Call_Centre__c = o.Call_Centre__c,
                        Who_Enrolled__c = UserInfo.getUserId()));
                        
                        
                        ol.converted_2_enrolment__c = TRUE;
                    }
                }
                if (OLI != NULL) {
                    update OLI;
                }
            }
    }
    
    try {
        insert createenrolment;
    }
    catch (Exception Ex){
        system.debug(Ex);
    }

All Answers

ManojjenaManojjena
HI ,
Please use below code ,error is comming as after insert and update as the record is saved to data base  so the record is always readonly .
.
Please use below code .
trigger CreateEnrolment on Opportunity (After update) {
	List<enrolment__c> createenrolment = new List <enrolment__c> ();
	List<Opportunity> oppLIst = new List <Opportunity> ();
    
	for (Opportunity o: trigger.new) {
	      if(Trigger.oldMap.get(o.Id).isWon !=true && o.isWon == true && o.converted_2_enrolment__c == FALSE )
				createenrolment.add(
                    new enrolment__c(
                    Campaign_Medium__c = o.Campaign_Medium__c,
                    Campaign_Name__c = o.Campaign_Name__c,
                    Product__c = o.Product__c,
                    Opportunity__c = o.id,
                    Account__c = o.AccountId,
                    Call_Centre__c = o.Call_Centre__c,
                    Who_Enrolled__c = UserInfo.getUserId()));
                    
                    o.converted_2_enrolment__c = TRUE;
                   oppLIst.add(o);
            }
    }

    try {
	   update oppLIst;
        insert createenrolment;
    }
    catch (DmlException Ex){
        system.debug(Ex);
    }
}

Choose best answer if it solves your problem .
Integration 39Integration 39
I ended up using OpportunityLineItem to get around the problem

trigger CreateEnrolment on Opportunity (after update) {

    List<enrolment__c> createenrolment = new List <enrolment__c> ();
    
    for (Opportunity o: trigger.new) {
            if (o.isWon == true && o.HasOpportunityLineItem == true) {
                String opptyId = o.Id;
            
                OpportunityLineItem[] OLI = [Select id,converted_2_enrolment__c From OpportunityLineItem where OpportunityId = :opptyId];
                for(OpportunityLineItem ol: OLI){
                    if (ol.converted_2_enrolment__c == FALSE) {
                        createenrolment.add(
                        new enrolment__c(
                        Campaign_Medium__c = o.Campaign_Medium__c,
                        Campaign_Name__c = o.Campaign_Name__c,
                        Product__c = o.Product__c,
                        Opportunity__c = o.id,
                        Account__c = o.AccountId,
                        Call_Centre__c = o.Call_Centre__c,
                        Who_Enrolled__c = UserInfo.getUserId()));
                        
                        
                        ol.converted_2_enrolment__c = TRUE;
                    }
                }
                if (OLI != NULL) {
                    update OLI;
                }
            }
    }
    
    try {
        insert createenrolment;
    }
    catch (Exception Ex){
        system.debug(Ex);
    }
This was selected as the best answer