0

I am getting the following error on my Apex class for line 144 "FATAL_ERROR System.LimitException: Apex CPU time limit exceeded"

Line 144 reads -

if(dayOfWeek == 'Saturday' || dayOfWeek == 'Sunday'){

Can anyone take a look at my class and help me to update it so that it will not hit the time limit ?

Here is the code

public class Zenefits_Time_Off implements Schedulable, Database.AllowsCallouts {

//query the list of holidays from the holiday object    
public static List<DateTime> HolidayList;

public Zenefits_Time_Off() {
    List<pse__HolidayObj__c> tempHolidayList = [SELECT pse__Date__c from pse__HolidayObj__c];
    for(pse__HolidayObj__c holiday : tempHolidayList) {
        HolidayList.add(holiday.pse__Date__c);
    }
}

public void execute(SchedulableContext SC) {
    Zenefits_Time_Off.makeCallout();
}


@future(callout = true)
public static void makeCallout() {

    List<Time_Off_Request__c> torToUpdate = new List<Time_Off_Request__c> ();
    list<pse__Timecard_Header__c> tchList = new list<pse__Timecard_Header__c> ();
    string url = 'xx'; 
    system.debug('before while');
    while (url != null) {
        url = makeHttpCall(url, torToUpdate, tchList);
        system.debug('after while');
    }
    insert (torToUpdate);
    insert(tchList);
    system.debug('SECONDTOR ' + torToUpdate);
}

public static String makeHttpCall(String url, List<Time_Off_Request__c> torToUpdate, List<pse__Timecard_Header__c> tchList) {
    string nextUrl = '';
    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setHeader('Authorization', 'Bearer xx');
    request.setEndpoint(url);
    request.setMethod('GET');
    HttpResponse response = http.send(request);
    // If the request is successful, parse the JSON response.
    if (response.getStatusCode() == 200) { 
        // Deserializes the JSON string into collections of posts.
        Map<String, Object> wrapper = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        if (wrapper.containsKey('data')) {
            Map<String, Object> wrapper2 = (Map<String, Object>) wrapper.get('data');
            if (wrapper2.containsKey('data')) {
                nextUrl = (String) wrapper2.get('next_url');
                system.debug('next URL' + nextUrl);
                List<Object> vacationRequests = (List<Object>) wrapper2.get('data');
                System.debug('Received the following vacation requests:');

                Map<String,map<String, Object>> ptoMap  = new Map<String,map<String, Object>>();
                set<string> employeeIdSet = new set<string>();

                for (Object vacationRequestWrapper : vacationRequests) {
                    Map<String, Object> vacationRequest = (Map<String, Object>) vacationRequestWrapper;
                    if (vacationRequest.get('status').equals('approved')) {
                        system.debug('vacationRequests ' + vacationRequest);
                        Map<String, Object> wrapper3 = (Map<String, Object>) vacationRequest.get('creator');

                        Map<String,Object> empValues = new Map<String,Object>(); 

                        string ptoUrl = (String) wrapper3.get('url');
                        string ptoId = (string)vacationRequest.get('id');
                        string employeeId = ptoUrl.substring(ptoUrl.length() - 7, ptoUrl.length() - 0);

                        empValues.put('startDate',vacationRequest.get('start_date'));
                        empValues.put('endDate',vacationRequest.get('end_date'));
                        empValues.put('ptoId',vacationRequest.get('id'));
                        empValues.put('hours',vacationRequest.get('hours'));
                        empValues.put('empId', employeeId);
                        ptoMap.put(ptoId, empvalues);
                        employeeIdSet.add(employeeId);
                        system.debug('ptoMap ' + ptoMap);
                    }
                } 
                Map<String, Object> tempEmpValues = new Map<String, Object>();
                Map<String,Object> contactVal = new Map<String,Object>();
                map<String,Id> conZenIdMap = new map<String,Id>();

                List<Contact> contactList = [SELECT Id, FirstName, LastName, Zenefits_ID__c FROM Contact WHERE Zenefits_ID__c IN : employeeIdSet];
                for (Contact con : contactList) {
                    System.debug('contactList ' + contactList);

                    conZenIdMap.put(con.Zenefits_ID__c,con.Id);

                    //tempEmpValues = ptoMap.get(con.Zenefits_ID__C);
                    //contactVal.put('ConId', con.id);
                }

                Time_Off_Request__c[] torList = [SELECT ID, Zenefits_ID__c FROM Time_Off_Request__c WHERE Zenefits_ID__c IN : ptoMap.keySet()];
                system.debug('torlist ' + torList);
                for(Time_Off_Request__c tor1 : torList) 
                {
                    ptoMap.remove(tor1.Zenefits_ID__c); //remove existing Time Off Requests
                }

                for(String zId: ptoMap.keyset()) 
                {
                    map<String,Object> currMap = ptoMap.get(zId);
                    map<String, Integer> hours = new Map<String, Integer>();

                    Time_Off_Request__c tor = new Time_Off_Request__c();
                    if(conZenIdMap.get((string)currMap.get('empId')) != null)
                    {
                        tor.Employee__c =conZenIdMap.get((string)currMap.get('empId'));
                        tor.Project__c = 'a8q8A000000CafTQAS';
                        tor.First_Day_Off__c = date.valueof((string)currMap.get('startDate'));
                        system.debug('FirstDay ' + tor.First_Day_Off__c);
                        tor.Last_Day_Off__c = date.valueof((string)currMap.get('endDate'));
                        tor.Status__c = 'Saved';
                        tor.Zenefits_ID__c = zId;
                        torToUpdate.add(TOR);
                        system.debug('torToUpdate' + torToUpdate);
                    }

                        datetime startDate = date.valueof((string) currMap.get('startDate'));

                        pse__Timecard_Header__c tch = new pse__Timecard_Header__c();
                        if(conZenIdMap.get((string)currMap.get('empId')) != null){

                        tch.CurrencyIsoCode = TestDataFactory.currencyCode;
                        tch.pse__Project__c = 'a8q8A000000CafTQAS';
                        tch.pse__Assignment__c = null;
                        tch.pse__Resource__c = conZenIdMap.get((string) currMap.get('empId'));
                        tch.pse__Start_Date__c = date.valueof((string) currMap.get('startDate'));
                        tch.pse__End_Date__c = date.valueof((string) currMap.get('endDate'));
                        tch.pse__Billable__c = false;
                        tch.pse__Time_Credited__c = true;
                        tch.pse__Time_Excluded__c = false;
                        tch.pse__Bill_Rate__c = null;
                        tch.pse__Cost_Rate_Amount__c = null;
                        tch.pse__Cost_Rate_Currency_Code__c = null;
                        tch.pse__Status__c = 'Saved';
                        tch.pse__Submitted__c = false;
                        tch.pse__Approved__c = false; 
                        tch.pse__Include_In_Financials__c = false; 

                        while(startdate < tch.pse__End_Date__c) {   

                            DateTime myDateTime = (DateTime) startdate;
                            String dayOfWeek = startdate.format('EEEE');

                            if(dayOfWeek == 'Saturday' || dayOfWeek == 'Sunday'){
                                continue;
                            }
                            else if (HolidayList.contains(startDate)){
                                continue;
                            }
                                else if (dayOfWeek == 'Monday'){

                                    hours.put('monday', 8); 
                                }
                                    else if (dayOfWeek == 'Tuesday'){

                                        hours.put('tuesday', 8);   
                                    }
                                        else if (dayOfWeek == 'Wednesday'){

                                            hours.put('wednesday', 8);
                                        }
                                            else if (dayOfWeek == 'Thursday'){

                                                hours.put('thursday', 8);
                                            }
                                                else if (dayOfWeek == 'Friday'){

                                                hours.put('friday', 8);
                                                }
                                                startDate = startdate.addDays(1);
                                                    }

                        tch.pse__Monday_Hours__c = integer.valueOf(hours.get('monday'));
                        tch.pse__Tuesday_Hours__c = integer.valueOf(hours.get('tuesday'));
                        tch.pse__Wednesday_Hours__c = integer.valueOf(hours.get('wednesday'));
                        tch.pse__Thursday_Hours__c = integer.valueOf(hours.get('thursday'));
                        tch.pse__Friday_Hours__c = integer.valueOf(hours.get('friday'));
                        tch.pse__Saturday_Hours__c = 0.0;
                        tch.pse__Sunday_Hours__c = 0.0;
                        tchList.add(tch);
                        system.debug('timecardList' + tchList);
                    }
                }
            }
        }
    }
 return nextUrl;
}

}

4
  • Have you tried separating some of this into an asynchronous call? Maybe after the response comes back?
    – nicolevy
    Commented Oct 29, 2019 at 19:54
  • I have not just because I am unaware of how to do so @nicolevy Commented Oct 29, 2019 at 19:55
  • Help me understand what's happening at line 25: while (url != null) {... It seems like you're making as many callouts as you can until you get a response. Is that intentional? What's the thought process behind that? Commented Oct 29, 2019 at 22:42
  • @ShaneSteinfeld yea that is intentional because the responses come in sets of 50 and I have to use the next URL to get each next set of 50 responses until all the responses are loaded. Commented Oct 30, 2019 at 10:04

1 Answer 1

0

@Kris, first of all, you have to reduce the fetching of record numbers. Like you may have to add some logic if any record fetched for processing or not. Second, you have to separate the call-out process and processing the response. What I mean in the makeHttpCall() just do the fetch operation, after that pass the response to an asynchronous process and do the response processing there. It will help a lot to reduce time limit.

You must log in to answer this question.

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