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
Tina Chang 6Tina Chang 6 

Why mass uploads cancel out scores calculated by Apex code?

Hello, all,

We recently implemented this Apex code "Account Grading Method" (attached below) in our system. When an account record is created or edited, a process in the Process Builder calls the Apex code to calculate the account grade. It calculates the score of an account based on the input of a group of fields called Account Intelligence fields and returns the result to a number field called "Account Overall Grade".

The problem is whenever we mass update accounts using an upload (like API Data Loader) or via nightly API calls, the score of the Account Overall Grade get zeroed out, and they need to be re-triggered individually. The account fields we mass updated were not even related to the Account Intelligence fields. When we tried to mass update accounts in list view, the score zeroed out as well. For example, we took an account list view and selected a bunch of records to do a mass in-line editing of one of the Account Intelligence fields, the "Account Overall Grade" field zeroed out.

Any idea on how we can continue to be able to mass update accounts without this happening, or what the issue is? The person who developed this account grading process and the code had left. Any help would be much much appreciated!
My apologies this is a lot of code. Thank you for your patience.

Account Grading Method
public with sharing class AccountGradingMethod {

    public static void AccountGrading(Set<String> setAcctGradingIds) {
        List<Account> lstAGS = new List<Account>();
        List<Account> lstUpdateAcct = new List<Account>();
        Map<String, Field_Value__mdt> mapFlds = new Map<String, Field_Value__mdt>();
        String strSOQLAcct;
        String strSOQLAcctGrade;
        Set<String> setFlds = new Set<String>();
        Set<String> setFldName = new Set<String>();
        String strScore;
        Decimal maxPossScore = 0;
        Decimal numberFlds = 0;

        strSOQLAcctGrade = 'SELECT Id';
        for(Field_Value__mdt fn:[SELECT Id, Field_Score_or_Multiplier__c, Picklist_API_Value__c, Use_Greater_then_or_Less_then__c, 
                                        Field_Name__r.Field_API_Name__c, Field_Name__r.Object__c, Field_Name__r.Type_of_Field__c,
                                        Greater_then__c, Less_then__c
                                    FROM Field_Value__mdt]){
            String mapKey;
            setFldName.add(fn.Field_Name__r.Field_API_Name__c);
            if(fn.Field_Name__r.Object__c == 'Account'){
                setFlds.add(fn.Field_Name__r.Field_API_Name__c);
            }
            if(fn.Use_Greater_then_or_Less_then__c){
                mapKey = fn.Field_Name__r.Field_API_Name__c + '-' + fn.Greater_then__c + '-' + fn.Less_then__c;
            }
            else{
                mapKey = fn.Field_Name__r.Field_API_Name__c + '-' + fn.Picklist_API_Value__c.deleteWhitespace();
            }
            mapFlds.put(mapKey, fn);
        }
        for(String f:setFlds){
            strSOQLAcctGrade += ', ' + f;
        }
        numberFlds = setFlds.size();
        strSOQLAcctGrade += ' FROM Account WHERE Id in :setAcctGradingIds';
        System.debug('strSOQLAcctGrade: ' + strSOQLAcctGrade);
        lstAGS = Database.query(strSOQLAcctGrade);
        strScore = System.Label.Max_Possible_Score;
        maxPossScore = Decimal.valueOf(strScore);

        for(Account ags:lstAGS){
            Decimal subTotal = 0;
            Decimal multiplier = 1;
            Decimal decTotal = 0;
            Decimal ecommTotal = 0;
            Decimal ecommMin = 0;
            Decimal ecommMax = 0;
            Decimal fldsPopulated = 0;
            Decimal precentComplete = 0;
            for(Field_Value__mdt fldVal:mapFlds.values()){
                String value;
                Decimal score = 0;
                Boolean skip = false;
                String fld = fldVal.Field_Name__r.Field_API_Name__c;
                String strKey;
                Decimal decValue = 0;
                if(setFldName.contains(fld)){
                    if(fldVal.Field_Name__r.Object__c == 'Account'){
                        value = String.valueOf(ags.get(fld));
                        if(value != '' && value != 'null' && value != null){
                            value = value.deleteWhitespace();
                            if(fldVal.Use_Greater_then_or_Less_then__c){
                                decValue = Decimal.valueOf(value);
                                System.debug('decValue: ' + decValue);
                                if(fldVal.Greater_then__c != null && fldVal.Less_then__c != null){
                                    if(fldVal.Greater_then__c > decValue && fldVal.Less_then__c < decValue){
                                     System.debug('if 1 fldVal.Less_then__c: ' + fldVal.Less_then__c);
                                        strKey = fld + '-' + fldVal.Greater_then__c + '-' + fldVal.Less_then__c;
                                    }
                                    else{
                                        skip = true;
                                    }
                                }
                                if(fldVal.Greater_then__c == null && fldVal.Less_then__c != null){
                                    if(fldVal.Less_then__c > decValue){
                                     System.debug('if 2 fldVal.Less_then__c: ' + fldVal.Less_then__c);
                                        strKey = fld + '-' + fldVal.Greater_then__c + '-' + fldVal.Less_then__c;
                                    }
                                    else{
                                        skip = true;
                                    }
                                }
                                if(fldVal.Greater_then__c != null && fldVal.Less_then__c == null){
                                    System.debug('if 3 fldVal.Greater_then__c : ' + fldVal.Greater_then__c );
                                    if(fldVal.Greater_then__c < decValue){
                                        strKey = fld + '-' + fldVal.Greater_then__c + '-' + fldVal.Less_then__c;
                                    }
                                    else{
                                        skip = true;
                                    }
                                }
                            }
                            else if (!fldVal.Use_Greater_then_or_Less_then__c){
                                strKey = fldVal.Field_Name__r.Field_API_Name__c + '-' + value;
                            }
                            if(!String.isBlank(strKey) && mapFlds.get(strKey) != null){
                                setFldName.remove(fld);
                                score = mapFlds.get(strKey).Field_Score_or_Multiplier__c;
                            }
                            if(score != null){
                                if(fld.startsWithIgnoreCase('e-commerce solutions')){
                                    skip = true;
                                    ecommTotal = ecommTotal + score;
                                    if(ecommMax<score){
                                        ecommMax = score;
                                    }
                                    if(ecommMin>score){
                                        ecommMin = score;
                                    }
                                }
                                if(fldVal.Field_Name__r.Type_of_Field__c == 'Score' && !skip){
                                    System.debug('fld: ' + fld);
                                    System.debug('Score: ' + score);
                                    subTotal = subTotal + score;
                                }
                                if(fldVal.Field_Name__r.Type_of_Field__c == 'Multiplier' && !skip){
                                    System.debug('fld: ' + fld);
                                    System.debug('multiplier: ' + score);
                                    multiplier = multiplier * score;
                                }
                            }
                        }
                        else{
                            fldsPopulated = fldsPopulated + 1;
                            setFldName.remove(fld);
                        }
                    }
                }
            }
            if(ecommTotal>=0){
                subTotal = subTotal + ecommMax;
            }
            else{
                subTotal = subTotal + ecommMin;
            }
            if(fldsPopulated == numberFlds){
                precentComplete = 100;      }
            else{
                precentComplete = ((numberFlds - fldsPopulated)/numberFlds)*100;
            }
            System.debug('subtotal: ' +  subTotal);
            subTotal = (subTotal/maxPossScore)*100;
            System.debug('subtotal after: ' +  subTotal);
            System.debug('multiplier: ' + multiplier);
            decTotal = subTotal*multiplier;
            System.debug('decTotal: ' + decTotal );
            Account a = new Account();
                a.Id = ags.Id;
                a.Account_Overall_Grade__c = decTotal;
                a.Percent_Complete__c = precentComplete;
            lstUpdateAcct.add(a);

        }
        if(lstUpdateAcct.size()>0){
            update lstUpdateAcct;
        }
    }
}

 
Best Answer chosen by Tina Chang 6
Tina Chang 6Tina Chang 6
Hi, Tuan Lu, thanks a lot for your response!  

The real issue seems to be the process in Process Builder as our Account Grading Method Apex Class was called through Process Builder.  The Process Builder has its limitations that it is non-bulky.  We created a trigger so it is called through Apex trigger instead of the process in the Process Builder and it is working correctly now. 

Thanks once again for your reply!
Tina

All Answers

Tuan LuTuan Lu
Hi Tina if this code works for one account update, it should work for mass updates too. The problem might be some where else like in the trigger or workflow trying to do something related. The developer has added many System.debug statements in the code so you should be able to turn on a debug log and see where the process is failing. I can help you with this if youd like. I also provide consulting services if you need changes. Please let me know. Thanks.

Tuan.
tlu@eigenx.com
 
Tina Chang 6Tina Chang 6
Hi, Tuan Lu, thanks a lot for your response!  

The real issue seems to be the process in Process Builder as our Account Grading Method Apex Class was called through Process Builder.  The Process Builder has its limitations that it is non-bulky.  We created a trigger so it is called through Apex trigger instead of the process in the Process Builder and it is working correctly now. 

Thanks once again for your reply!
Tina
This was selected as the best answer