0

I am getting salesforce "Apex CPU time limit exceed exception" in the below code. Please help me to optimize the code or how to sort out this issue. Any help would be greatly appriciated.

public static Map<String, Object> getCFAccountOverdue(Set<String> cfAccountIdSet ) {
    Map<String, Object> cfAccountOverdueMap = new Map<String, Object>();
    Map<String, Decimal> overdueDateRangeMap = new Map<String, Decimal>();

    for(Schema.pickListEntry eachVal : CF_Claim__c.Overdue_Date_Ranges__c.getDescribe().getPicklistValues()){
        overdueDateRangeMap.put(eachVal.getValue(), 0);
    }
        for(CF_Claim__c eachClaim : [SELECT CF_Account__c, Overdue_In_Days__c, Amount__c  FROM CF_Claim__c  WHERE CF_Account__c IN:cfAccountIdSet AND Status__c = 'Open' ORDER BY CF_Account__c,Overdue_In_Days__c Nulls last]) {                
            if( !cfAccountOverdueMap.containsKey(eachClaim.CF_Account__c) ) {   
                Map<String, Decimal> dateRangeMap = new Map<String, Decimal>(); 
                dateRangeMap.putAll(overdueDateRangeMap);
                dateRangeMap.put(eachClaim.Overdue_In_Days__c, eachClaim.Amount__c != null ? eachClaim.Amount__c : 0);
                cfAccountOverdueMap.put(eachClaim.CF_Account__c, dateRangeMap);                    
            }else {
                Map<String, Decimal> dateRangeMap = (Map<String, Decimal>)cfAccountOverdueMap.get(eachClaim.CF_Account__c);
                dateRangeMap.put(eachClaim.Overdue_In_Days__c, ((dateRangeMap.get(eachClaim.Overdue_In_Days__c)) + (eachClaim.Amount__c != null ? eachClaim.Amount__c : 0)));
                cfAccountOverdueMap.put(eachClaim.CF_Account__c, dateRangeMap);
            }
        }
    return cfAccountOverdueMap; 
}
2
1

From what I understood from your code, you're summing up Amount by Account and some picklist.

Please, consider using GROUP BY with ROLLUP and SUM aggregate function. I think they'll give you what you need and might solve your CPU time issue.

Here's a sample code for your method. I didn't test it, sorry, but it should work in general. Will gladly provide further assistance.

public static Map<Id, Map<String, Decimal>> getCFAccountOverdue(Set<String> cfAccountIdSet ) {
    Map<Id, Map<String, Decimal>> cfAccountOverdueMap = new Map<Id, Map<String, Decimal>>();
    Map<String, Decimal> overdueDateRangeMap = new Map<String, Decimal>();

    for(Schema.pickListEntry eachVal : CF_Claim__c.Overdue_Date_Ranges__c.getDescribe().getPicklistValues()){
        overdueDateRangeMap.put(eachVal.getValue(), 0);
    }

    AggregateResult[] aggrs = [
        // sumAmount is an alias for the SUM result
        SELECT SUM(Amount__c) sumAmount,
            CF_Account__c, Overdue_In_Days__c,
            // we need GROUPING to indicate if we need to include this in mapping
            GROUPING(CF_Account__c) grpAcc,
            GROUPING(Overdue_In_Days__c) grpOverdue
        FROM CF_Claim__c
        //HAVING is WHERE for aggregate queries
        HAVING CF_Account__c IN :cfAccountIdSet
        // grouping by 2 fields
        GROUP BY 
            ROLLUP(
                CF_Account__c,
                Overdue_In_Days__c
            )
    ];

    for (AggregateResult res : aggrs) {
        if (res.get('grpAcc') == 1 || res.get('grpOverdue') == 1) {
            // it's a total aggr by only one of the fields
            continue;
        }
        Id accId = res.get('CF_Account__c');
        if(!cfAccountOverdueMap.containsKey(accId)) {   
            cfAccountOverdueMap.put(accId, new Map<String, Decimal>());
            cfAccountOverdueMap.get(accId).putAll(overdueDateRangeMap);
        }
        String overdue = res.get('Overdue_In_Days__c');
        Decimal sumAmount = res.get('sumAmount');
        cfAccountOverdueMap.get(accId).put(overdue, sumAmount);
    }
    return cfAccountOverdueMap;
}
2
  • Hi There.. Great thanks for your reply and great code optimization. But my problem here is "Overdue_In_Days__c" field is formula field not able to group by error i am getting. If in case any other incite would be great help :) Aug 24 '18 at 3:26
  • @Pulikunta Fazur I was thinking how to help in your situation without building a crazy workaround with duplicating the formula result to some other field, or calculating it without formula... And I'm sorry, nothing came my mind :( You still can vote up for idea on allowing grouping by formulas on success.salesforce :)
    – nchursin
    Aug 24 '18 at 17:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.