1

I have written the trigger code for skipping weekends and Holidays from Holiday custom object

Trigger code:

trigger ignoreweekends on order (before insert,before update) {
    for (order so : Trigger.new) {
        list<account> cd =[select id,JDE_Date_Delivery_Offset__c from account where id =:so.accountid];
        Map<date, Holiday__c> myMap = new Map<date, Holiday__c>(); 

        for(Holiday__c objCS : [Select id, Date__c from Holiday__c]) {
            myMap.put(objCS.Date__c , objCS);
            for(account et : cd) {
                for(integer i=0;i<=et.JDE_Date_Delivery_Offset__c;i++) {
                    Datetime dt = DateTime.newInstance(Date.today() +et.JDE_Date_Delivery_Offset__c.longvalue(), Time.newInstance(0, 0, 0, 0));
                    String dayOfWeek=dt.format('EEEE');
                    if(dayOfWeek == 'saturday' || dayOfWeek == 'sunday'|| mymap.containskey(objCS.Date__c))                 
                        et.JDE_Date_Delivery_Offset__c = et.JDE_Date_Delivery_Offset__c+ 1;

                    so.JDE_Synchronization_Date__c = Date.today().addDays(et.JDE_Date_Delivery_Offset__c.intValue());
                }
            }
        }
    }
}   

Is it possible to reduce the code and bulkify the code

After inserting the record I got the error like:

Apex trigger ignoreweekends caused an unexpected exception, contact your administrator: ignoreweekends: System.LimitException: Apex CPU time limit exceeded

Why this error occuring,please anyone rectify the mistake

1
  • 1
    The first thing you need to do is make soql outside for loop. You can use collection variable to store ids or directly use trigger context variables.
    – Reshma
    Mar 7, 2017 at 11:53

3 Answers 3

0

Your code has following problems:

  1. SOQL inside for loop, likely to hit SOQL 101 exception.
    • Use Set/List/Map in this situation to pass on to your SOQL
  2. you have 4 for loops in your code referring to the collection from other object. CPU time limit exceeded error exception can be and has raised in your case.
    • solutions: Use Maps in such situations

Proposed code after changes (not tested, but it should give you an idea where to take things forward)

trigger ignoreweekends on order (before insert,before update) {

    Set<id> accountIds = new Set<Id>();
    for (order ord : Trigger.new) {
        accountids.add(ord.AccountId)
    }
    // pass the set of account ids to SOQL to fetch Accounts
    map<id, account> mapOfAccounts = new map<id, account>([select id,JDE_Date_Delivery_Offset__c from account where id IN: accountIds]);
    // get holidays list
    List<Holiday__c> holidays = new List<Holiday__c>([Select id, Date__c from Holiday__c]);
    // build map with date as key, and holiday object as value to be referred later in the code
    Map<date, Holiday__c> mapOfHolidays = new Map<date, Holiday__c>(); 
    for (Holiday__c holiday: holidays) mapOfHolidays.put(holiday.date, holiday);

    for (order so : Trigger.new) {
        Account acc = mapOfAccounts.get(so.AccountId); 
        for(integer i=0;i<=acc.JDE_Date_Delivery_Offset__c;i++) {
            Datetime dt = DateTime.newInstance(Date.today() +acc.JDE_Date_Delivery_Offset__c.longvalue(), Time.newInstance(0, 0, 0, 0));
            String dayOfWeek=dt.format('EEEE');
            if(dayOfWeek == 'saturday' || dayOfWeek == 'sunday'|| mapOfHolidays.containskey(objCS.Date__c))                 
            acc.JDE_Date_Delivery_Offset__c = acc.JDE_Date_Delivery_Offset__c+ 1;

            so.JDE_Synchronization_Date__c = Date.today().addDays(acc.JDE_Date_Delivery_Offset__c.intValue());
        }
    }
}
1
0

The Maximum CPU time on the salesforce servers - 10,000 milliseconds (Synchronous limit) 60,000 milliseconds(Asynchronous limit).

Please remove muliple loop from your code. You are using nested loop then try to use collection in code.You may have to go in and edit and refine some of your code, This may be a good place to start.

0
0

Please refer below comments:-
1. Avoid SOQL inside loops.
2. Always use collections to bulkify your code.
3. Avoid lot of nested loops which increase the processing time.

trigger ignoreweekends on order (before insert,before update) {
    for (order so : Trigger.new) {
        //Avoid SOQL Inside For Loop Instead Use Collections To Bulkify your code
        list<account> cd =[select id,JDE_Date_Delivery_Offset__c from account where id =:so.accountid];
        Map<date, Holiday__c> myMap = new Map<date, Holiday__c>(); 

   } 
/******************End**************/

You can try something like following, this just to demonstrate you how you can avoid SOQL inside for loop and how you can use collection to bulkify your code.

trigger ignoreweekends on order (before insert,before update) {
    //Declare a set
    Set<Id> setAccountIds = new Set<Id>

    //Prepare Set of Account Ids
    for(order objOrder : Trigger.new){
        setAccountIds.add(objOrder.accountid);
    }

    for (order so : Trigger.new) {
        Map<date, Holiday__c> myMap = new Map<date, Holiday__c>();
        for(Holiday__c objCS : [Select id, Date__c from Holiday__c]) {
            myMap.put(objCS.Date__c , objCS);
            // To iterate over Accounts use like following which helps 
            // to retrive data using queryMore
            for(account et : [select id,JDE_Date_Delivery_Offset__c from account where id IN : setAccountIds]){
                //Avoid nested loops to reduce processing time, you need to
                // optimize your logic here!
            }
        }
    }
}
0

You must log in to answer this question.