I would like to automatically update the Stage field on all child opportunities to Closed Won when a custom checkbox field ("Payment Info on File") is checked on the parent account record.

I came close to achieving this functionality by modifying some helpful code provided by Keith C. on a similar thread (Trigger to update opportunity stage based on Account Status):

trigger moveToClosedWon on Account(after update)  {

Set<Id> accountIds = new Set<Id>();
for (Account acc : Trigger.new) {
     Account old = Trigger.oldMap.get(acc.Id);
     if (acc.Payment_Info_on_File__c = true && acc.Payment_Info_on_File__c != old.Payment_Info_on_File__c) {

if (!accountIds.isEmpty()) {
    List<Opportunity> opps = [
            select Id, StageName
            from Opportunity
            where AccountId in: accountIds
            and StageName != 'Closed Won'
    if (!opps.isEmpty()) {
        for (Opportunity opp : opps) {
            opp.StageName = 'Closed Won';
        update opps;

When I tested the trigger, I received the following error message:

Error:Apex trigger moveToClosedWon caused an unexpected exception, contact your administrator: moveToClosedWon: execution of AfterUpdate caused by: System.FinalException: Record is read-only: Trigger.moveToClosedWon: line 6, column 1

How can I accomplish my goal?

  • 1
    acc.Payment_Info_on_File__c = true is an assignment that is producing the error. So the first thing to do is to change to == true..
    – Keith C
    Jul 12, 2015 at 23:23
  • Keith - thank you for your quick response - it is working perfectly now!
    – Scott
    Jul 13, 2015 at 1:07

2 Answers 2


You could write you trigger logic like this:

trigger UpdateStageOnOpportunity on Account (after update) {
        set<Id>AccId = new set<Id>();
        for(Account Acc : trigger.new){
           if(Acc.Id != null && Acc.MyLightningP__Payment_Info_on_File__c == true){

        map<Id,Opportunity>OppMap = new map<Id,Opportunity>([select Id, name, StageName 
                                                               from Opportunity
                                                              where AccountId in: AccId]);

        for(Account Acc : trigger.new){
                OppMap.get(Acc.Id).StageName='Closed Won';
        update OppMap.values();
trigger updateopportunities on Account (before update) {
    Set<Id> accountIds = new Set<Id>();
    for (Account ac: trigger.new){
        if (ac.Payment_Info_on_File__c == true){
    List<opportunity> oppsToUpdate = new List<opportunity>();
    for (Opportunity opp : [Select Id,Name, StageName from opportunity where AccountId=:accountIds]){
        opp.StageName ='Closed Won';        
    update oppsToUpdate;      

  • Did you mean for this to be an answer? If so, please add some explanation. Pure code dumps are not especially useful.
    – Adrian Larson
    Sep 21, 2016 at 19: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.