+ Start a Discussion
shobana shobana 1shobana shobana 1 

Trigger to update the value from one object to another object without relationship

My scenario is to calculate the holidays for an opportunity.  For this i have created an custom field(DateType: Integer) in opportunity called "Holidayslist__c"(This field i want to display no of holidays).

1.If my opportunity is in "Open" , i want to calculate the holidays between the opportunity CreatedDate field to TODAY.

2.If Opportunity is "Closed", i want to calculate the holidays between the CreatedDate field to ClosedDate.

I wrote a trigger but its not working and it will hit the governer limit. Can anyone give me suggestion how to do this.

Thanks In Advance.

trigger testholidays on Opportunity (before insert, before update) 
{
List<opportunity> lstOpp = new List<opportunity>();
        List<opportunity> lstOppToUpdate = new List<opportunity>();
        Map<Date,Integer> mapActivDateToCount = new Map<Date,Integer>();
        Set<Date> setDateOppCreated = new Set<Date>();
        list<opportunity> opp1 = [select id,Name,CreatedDate,Holidayslist__c
                                    from opportunity 
                                    where IsClosed =False];      
        for(Opportunity objOpp : opp1 )
        {
            lstOpp.add(objOpp);
            setDateOppCreated.add(objOpp.CreatedDate.date());
            
        }
        
         for(Holiday objHoilday : [ SELECT Id, ActivityDate
                                    FROM Holiday
                                    WHERE ActivityDate < TODAY 
                                    AND ActivityDate >: setDateOppCreated
                                    ])
        {
            Date dt = objHoilday.ActivityDate;
            if(mapActivDateToCount.containsKey(dt))
            {
                mapActivDateToCount.put(dt, mapActivDateToCount.get(dt)+1);
            }
            else
            {
                mapActivDateToCount.put(dt, 1);
            }
        }
        
        // I am not getting any way to avoid for inside for .
        for(Opportunity objOpp : lstOpp)
        {
           opp1[0].Holidayslist__c = 0;

            for(Date dtActivity : mapActivDateToCount.keySet())
            {
                if(dtActivity < objOpp.CreatedDate.date())
                {
                    opp1[0].Holidayslist__c +=  mapActivDateToCount.get(dtActivity);
                }
            }
            lstOppToUpdate.add(objOpp);
        }
        
        system.debug('=====lstOppToUpdate===='+lstOppToUpdate);
        
        Database.update(lstOppToUpdate, true);

}
Best Answer chosen by shobana shobana 1
JethaJetha
Please find updated code : 
trigger testholidays on Opportunity (after insert, after update) 
{
    List<opportunity> lstOpp = new List<opportunity>();
    set<Date> holidayDate = new set<Date>();
        
    for(Holiday objHoilday : [ SELECT Id, ActivityDate FROM Holiday ])
    {
        holidayDate.add(objHoilday.ActivityDate);
    }
    
    // I am not getting any way to avoid for inside for .
    for(Opportunity objOpp : trigger.new)
    {
        Integer holList = 0;
        Opportunity opp = new Opportunity(Id = objOpp.Id);
        for(Date dtActivity : holidayDate)
        {
            if(!objOpp.IsClosed && dtActivity > objOpp.CreatedDate && dtActivity > System.Today())
            {
                system.debug('=======>In IF ');
                holList ++;
            }
            else if (objOpp.IsClosed && dtActivity > objOpp.CreatedDate && dtActivity < objOpp.closeDate)
            {
                system.debug('=======>In IF Elsie');
                holList +=1;
            }
        }
        opp.Holidayslist__c = holList;
        lstOpp.add(opp);
    }
    
    if(checkRecursive.runOnce())
    {
        Database.update(lstOpp, true);
    }

All Answers

JethaJetha
Hi Shobhana,

Please try below modified code : 
trigger testholidays on Opportunity (after insert, after update) 
{
	List<opportunity> lstOpp = new List<opportunity>();
    set<Date> holidayDate = new set<Date>();
	    
	for(Holiday objHoilday : [ SELECT Id, ActivityDate FROM Holiday WHERE ActivityDate < TODAY 
								AND ActivityDate >: setDateOppCreated ])
	{
		holidayDate.add(objHoilday.ActivityDate);
	}
	
	for(Opportunity objOpp : trigger.new)
	{
	    Integer holList = 0;
		Opportunity opp = new Opportunity(Id = objOpp.Id);
		for(Date dtActivity : holidayDate)
		{
			if(!objOpp.IsClosed && dtActivity > objOpp.CreatedDate.date() && dtActivity > objOpp.now().date())
			{
				holList ++;
			}
			else if (objOpp.IsClosed && dtActivity > objOpp.CreatedDate.date() && dtActivity > objOpp.closeDate.date())
			{
				holList ++;
			}
		}
		opp.holList = holList;
		lstOpp.add(opp);
	}
	
	Database.update(lstOppToUpdate, true);
}

 
shobana shobana 1shobana shobana 1

Hi Jetha SF

Thank you for your reply. It's throwing an error like "Variable does not exist: setDateOppCreated". Again we want to write an query for opportunity ?

JethaJetha
Please find updated code : 
trigger testholidays on Opportunity (after insert, after update) 
{
    List<opportunity> lstOpp = new List<opportunity>();
    set<Date> holidayDate = new set<Date>();
        
    for(Holiday objHoilday : [ SELECT Id, ActivityDate FROM Holiday ])
    {
        holidayDate.add(objHoilday.ActivityDate);
    }
    
    // I am not getting any way to avoid for inside for .
    for(Opportunity objOpp : trigger.new)
    {
        Integer holList = 0;
        Opportunity opp = new Opportunity(Id = objOpp.Id);
        for(Date dtActivity : holidayDate)
        {
            if(!objOpp.IsClosed && dtActivity > objOpp.CreatedDate && dtActivity > System.Today())
            {
                system.debug('=======>In IF ');
                holList ++;
            }
            else if (objOpp.IsClosed && dtActivity > objOpp.CreatedDate && dtActivity < objOpp.closeDate)
            {
                system.debug('=======>In IF Elsie');
                holList +=1;
            }
        }
        opp.Holidayslist__c = holList;
        lstOpp.add(opp);
    }
    
    if(checkRecursive.runOnce())
    {
        Database.update(lstOpp, true);
    }
This was selected as the best answer
shobana shobana 1shobana shobana 1

Hi  Jetha SF

Thank you for your reply. But its throwing an error " Variable does not exist: checkRecursive". Can you please explain why you used that one.

JethaJetha
Ohh Sorry Shobana,

This class is used to stop recurssive trigger.

Please create below class in your Org and then run the code :
public Class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }
}

 
shobana shobana 1shobana shobana 1
Hi Jetha SF
Thank you its working