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
    Commented Jul 12, 2015 at 23:23
  • Keith - thank you for your quick response - it is working perfectly now!
    – Scott
    Commented 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
    Commented Sep 21, 2016 at 19:17

You must log in to answer this question.

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