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
Vishnu7700Vishnu7700 

If opportunity is closedlost then the realted account activites should be colsed

I had tried with logic as below can any one help to correct the logic.

Code

 

List<Opportunity> opplist = [Select id from opportunity where StageName =:'Prospecting' and StageName =:'Closed Lost' Limit 2];

List<Task> listtask = [Select id,whatId from Task where Id IN :opplist.Id];

if(trigger.isupdate||trigger.isdelete){

if(Task task : Trigger.old)

 if(o.StageName == 'ClosedLost'){
            task.Status == 'Completed';
            listtask.add(task);
            }

      update listtask;

}

Best Answer chosen by Admin (Salesforce Developers) 
Dhaval PanchalDhaval Panchal
Use
if(o.StageName == 'ClosedLost' && o.StageName != Trigger.OldMap.get(o.Id).StageName)

instead of

if(o.StageName = 'ClosedLost' && o.StageName != Trigger.OldMap.get(o.Id).StageName)

All Answers

arag73877arag73877
task.Status ='completed';
Dhaval PanchalDhaval Panchal
trigger trgCloseLostOpportunity on Opportunity (before update){
	Set<ID> setOppIds = new Set<ID>();
	for(Opportunity opp:Trigger.New){
		if(opp.StageName == 'ClosedLost' && opp.StageName != Trigger.oldMap.get(opp.Id).StageName){
			setOppId.add(opp.Id);
		}
	}
	List<Task> lstTask = new List<Task>();
	if(setOppId.size()>0){
		lstTask = [Select id, Status From Task where WhatId in:setOppId];
		if(lstTask.size()>0){
			for(Task tsk:lstTask){
				tsk.Status = 'Completed';
			}
			Update lstTask;
		}
	}
}

 You have to compare opportunity id with "WhatId" field of Task.

arag73877arag73877
This is working right??
Vishnu7700Vishnu7700

Hi error as AND operator can only be applied to Boolean expressions

 

at line if(opp.StageName == 'ClosedLost' && opp.StageName != Trigger.oldMap.get(opp.Id).StageName){

Dhaval PanchalDhaval Panchal
Hey, I don't see any issue in this line, can you please copy entire code from your editor?
Dhaval PanchalDhaval Panchal

There was one mistake in variable "setOppId", declaration was "setOppIds" and rest of part i used "setOppId". I have compiled my code and now it is successfully compiled. use below code.

 

 

trigger trgCloseLostOpportunity on Opportunity (before update){
    Set<ID> setOppId = new Set<ID>();
    for(Opportunity opp:Trigger.New){
        if(opp.StageName == 'Closed Lost' && opp.StageName != Trigger.oldMap.get(opp.Id).StageName){
            setOppId.add(opp.Id);
        }
    }
    List<Task> lstTask = new List<Task>();
    if(setOppId.size()>0){
        lstTask = [Select id, Status From Task where WhatId in:setOppId];
        if(lstTask.size()>0){
            for(Task tsk:lstTask){
                tsk.Status = 'Completed';
            }
            Update lstTask;
        }
    }
}

 

Vishnu7700Vishnu7700
trigger MultipleRealScenariostrigger on Opportunity (before insert, before update, before delete ){
         //varaibles hold open and closed types StageName
         Set<string> openstages = new Set<string>();
         Set<string> closedstages = new Set<string>();
        
        //Add open stages in the set
        openstages.add('Prospecting');
        openstages.add('Qualification');
        openstages.add('Needs Analysis');
        openstages.add('Value Proposition');
        openstages.add('Id. Decision Makers');
        openstages.add('Perception Analysis');
        openstages.add('Proposal/Price Quote');
        openstages.add('Negotiation/Review');
        //Add close stages in the set
        closedstages.add('Closed Won');
        closedstages.add('Closed Lost');
        
        //Get list of opp with stagename as Prospecting and userinfo
        List<Opportunity> opplist = [Select id from opportunity where StageName =:'Prospecting' and StageName =:'Closed Lost' Limit 2];
        String userprofile = [Select name from profile where Id = :UserInfo.getProfileId()].name;
        List<Task> lsttask = new List<Task>();//List of Tasks
        Set<ID> setOppIds = new Set<ID>();//Holds set of opportunity Ids
                //Iterate through opportunity object
        for(opportunity o : Trigger.new){
            //trigger of contextvaraibles isinsert and isupdate
            if(trigger.isinsert||trigger.isupdate){
                if(trigger.isupdate){
                    //Condition to check stagename with old value if it is close can not be changed to open stage
                    if(Trigger.oldMap.get(o.Id).StageName == 'Closed' && o.StageName == 'Open'){
                    o.addError('Stage can not be move from closed to open');
                    return;
                    }
                    /*if(closedstages.contains(system.Trigger.oldMap.get(o.Id).StageName)&& openstages.contains.(o.StageName)){
                    o.adderror('Stage can not be moved back form Close to Open');
                    }*/
                }
                //Verify condition that opportunity stagename is closedLost
                if(o.StageName = 'ClosedLost' && o.StageName != Trigger.OldMap.get(o.Id).StageName){
                    setOppIds.add(o.Id);
                }
                //if opportunity stage name is ClosedLost then associated tasks status is updated to Completed
                If(o.size()>0){
                    lsttask = [Select id, Status from Task where WhatId in :setOppIds];
                        if(lsttask.size()>0){
                            for(Task tsk : lsttask){
                                tsk.Status = 'Completed';
                            }
                            update lsttask;                         }
                }
                //Check the opplist variable size if size is greater then 1 through error
                if(opplist.size()>1){
                o.adderror('Already one Opportunity with open status present');
                }
            
            //Trigger for context variable isupdate and isdelete    
            if(trigger.isupdate||trigger.isdelete){
                //check condition that stagename as closedlost and userprofile is sys admin
                if(o.StageName =='ClosedLost'&& userprofile !='System Administrator'){
                //Through error while user not equal to sys admin trys to delete or modify closed lost opportunity
                o.adderror('Only Admin can delete once opportunity status is closed');
                }
            }
            
            }
        }  
    }

 Above is the code and highlited line are part of recent scenario.

Dhaval PanchalDhaval Panchal
One more minor change. you have used stage name "ClosedLost" but it should "Closed Lost". use code from my last message. its working for me.
Dhaval PanchalDhaval Panchal
Hey you are doing DML operation in Loop....will create problem for you.
Vishnu7700Vishnu7700

I had changed as u said like ClosedLost to Closed Lost

even though getting same error as AND operator can only be applied to Boolean expressions at line 40 column 51

 

Can you help out how to aviod DML in loop?

Dhaval PanchalDhaval Panchal

I have removed dml operation from loop, see below and use this code.

 

trigger MultipleRealScenariostrigger on Opportunity (before insert, before update, before delete ){
         //varaibles hold open and closed types StageName
         Set<string> openstages = new Set<string>();
         Set<string> closedstages = new Set<string>();
        
        //Add open stages in the set
        openstages.add('Prospecting');
        openstages.add('Qualification');
        openstages.add('Needs Analysis');
        openstages.add('Value Proposition');
        openstages.add('Id. Decision Makers');
        openstages.add('Perception Analysis');
        openstages.add('Proposal/Price Quote');
        openstages.add('Negotiation/Review');
        //Add close stages in the set
        closedstages.add('Closed Won');
        closedstages.add('Closed Lost');
        
        //Get list of opp with stagename as Prospecting and userinfo
        List<Opportunity> opplist = [Select id from opportunity where StageName =:'Prospecting' and StageName =:'Closed Lost' Limit 2];
        String userprofile = [Select name from profile where Id = :UserInfo.getProfileId()].name;
        List<Task> lsttask = new List<Task>();//List of Tasks
        Set<ID> setOppIds = new Set<ID>();//Holds set of opportunity Ids
                //Iterate through opportunity object
        for(opportunity o : Trigger.new){
            //trigger of contextvaraibles isinsert and isupdate
            if(trigger.isinsert||trigger.isupdate){
                if(trigger.isupdate){
                    //Condition to check stagename with old value if it is close can not be changed to open stage
                    if(Trigger.oldMap.get(o.Id).StageName == 'Closed' && o.StageName == 'Open'){
						o.addError('Stage can not be move from closed to open');
						return;
                    }
                    /*if(closedstages.contains(system.Trigger.oldMap.get(o.Id).StageName)&& openstages.contains.(o.StageName)){
						o.adderror('Stage can not be moved back form Close to Open');
                    }*/
                }
                //Verify condition that opportunity stagename is closedLost
                if(o.StageName = 'ClosedLost' && o.StageName != Trigger.OldMap.get(o.Id).StageName){
                    setOppIds.add(o.Id);
                }
                //Check the opplist variable size if size is greater then 1 through error
                if(opplist.size()>1){
					o.adderror('Already one Opportunity with open status present');
                }
            
            //Trigger for context variable isupdate and isdelete    
            if(trigger.isupdate||trigger.isdelete){
                //check condition that stagename as closedlost and userprofile is sys admin
                if(o.StageName =='ClosedLost'&& userprofile !='System Administrator'){
                //Through error while user not equal to sys admin trys to delete or modify closed lost opportunity
					o.adderror('Only Admin can delete once opportunity status is closed');
                }
            }
            
            }
        }  
		
		//if opportunity stage name is ClosedLost then associated tasks status is updated to Completed
		If(setOppIds.size()>0){
			lsttask = [Select id, Status from Task where WhatId in :setOppIds];
				if(lsttask.size()>0){
					for(Task tsk : lsttask){
						tsk.Status = 'Completed';
					}
					update lsttask;                         }
		}
    }

 

Dhaval PanchalDhaval Panchal
Use
if(o.StageName == 'ClosedLost' && o.StageName != Trigger.OldMap.get(o.Id).StageName)

instead of

if(o.StageName = 'ClosedLost' && o.StageName != Trigger.OldMap.get(o.Id).StageName)
This was selected as the best answer
Vishnu7700Vishnu7700

Yes it working fine now. Assigned Kodos

Thanks Dhaval Panchal

Dhaval PanchalDhaval Panchal
Thanks Vishnu.
Imran PatelImran Patel

Hey.. Great Solution...