-4

If case status got change for certain record type, new support record should get created. I configured status and record type combination in custom setting

I am trying to avoid nested loop in my trigger that's why I am using map. I checked the debug logs, and my trigger is not entering the second for loop. Please suggest me what am i missing here. Trigger is working if I am using nested loop. In that case trigger is creating more than 1 record in production

trigger NewSuppoSTCaseRecord on Case (after insert, after update) { 
    Map<Id, Suppourt_Settings__c> SuppourtRecordTypeIdMap = new Map<Id, Suppourt_Settings__c>();
    Map<string,string> caseRecordTypeMap = new Map<string,string>();
    set<string> caseRecordTypeSet = new set<string>();
    set <Case> caselist1 = new set<Case>();
    List<Suppourt_Settings__c> SuppouCaseListCaseList = new List<Suppourt_Settings__c>();
    string rec_type;
    RecordtypeClass RecordtypeCS = new RecordtypeCSClass();// fetching all custom setting values in the class
    Map<string, Suppourt_Settings__c> allRecordTypeMap = RecordtypeClass.CaseRecordtypeMap; //Get all Custom setting records
    system.debug('allRecordTypeMap :NewServicenetrecord:' + allRecordTypeMap);
    for(Suppourt_Settings__c ST1 : allRecordTypeMap.values()){
        SuppourtRecordTypeIdMap.put(ST1.RecordtypeId__c, ST1);
        caseRecordTypeSet.add(ST1.RecordtypeId__c);             
    }
    for(Case c1 :trigger.new){
        if( SuppourtRecordTypeIdMap.containsKey(c1.RecordTypeId)){
            Suppourt_Settings__c ST  =  SuppourtRecordTypeIdMap.get(c1.RecordTypeId);            
            rec_type = c1.RecordTypeId; 
            if(ST.RecordTypeId__c ==  rec_type){
                if( caseRecordTypeSet.contains(rec_type)){
                    if (c1.Status == status  && c1.Private__c != true){
                        caselist1.add(c1);
                    }
                }
            }

            if(caselist1.size() > 0) {
                for(case c : caselist1){
                    Suppourt_Settings__c ST  SuppourtCase = new Suppourt_Settings__c();
                    if(caseRecordTypeSet.contains(rec_type)){
                        if(c.RecordTypeId == ST.RecordtypeId__c){
                            if(c.Status == ST.Status__c){  
                                rec_type = c.RecordTypeId;                                               
                                SuppourtCase.Case__c = c.ID;
                                SuppourtCase.Send_mail__c = true;
                            }
                        }
                    }
                    if(SuppourtCase.Notification_Type__c != null && SuppourtCase.Notification_Type__c != '') {
                        SuppoSTCaseList.add(SuppoSTCase);                
                    }
                 }
              }
  • A couple of things I'd like to mention, Divya. Knowing when and how to use spacing and punctuation in sentences is important. If you don't pay enough attention to the basics of punctuation, it becomes a lot harder to read and understand what you're trying to tell people. On a similar note, being consistent with your code (indentation, variable naming, bracket placement, spacing between operators, etc...) is also important. If you don't do that, then your code becomes hard to read, which decreases your chances of getting your issue resolved. – Derek F Jul 8 '19 at 14:21
  • 3
    Putting "urgent" in your question is more harmful than helpful. Actions speak louder than words. If it is truly urgent, then you can show that by being attentive and replying quickly when asked for clarification in the comments. Even then, keep in mind that basically everyone here is volunteering their time and experience. It might be urgent for you, but not for others here. If it is truly something that needs to be taken care of now, then hiring a contractor or a consultant is probably your best bet. – Derek F Jul 8 '19 at 14:27
  • 3
    It seems like your trigger is incomplete. Based on the code provided so far, I don't see any debug statements inside or after your loops. How do you know that your second loop isn't being executed? It also looks like you still have your nested loop (contrary to what you've said). You should edit your question so that the code in your question is able to be compiled (and keep in mind the points about formatting that I mentioned previously). – Derek F Jul 8 '19 at 14:34
  • It is not acceptable behavior to blank your question content after the community has engaged and provided answers. Please do not continue this behavior. – David Reed Jul 9 '19 at 11:57
1

I don't think anyone can provide a complete and conclusive answer to this question because it is highly data-dependent, and because critical code is omitted - like RecordtypeClass.CaseRecordtypeMap. What you need to do to debug this code is really to understand how your Case and Custom Settings data are interacting with your logic, and that's something you'll have to work through in your org.

You can make this process easier, though, by streamlining your logic and correcting some clear mistakes.

You have a lot of conditionals and comparisons that do nothing at all or are redundant. Removing this excess logic will make following the flow of control in your code much easier. Here's an example:

    Suppourt_Settings__c ST  =  SuppourtRecordTypeIdMap.get(c1.RecordTypeId);            
    rec_type = c1.RecordTypeId; 
    if(ST.RecordTypeId__c ==  rec_type){

This if is always true. You just got ST by indexing with rec_type (which is equal to c1.RecordTypeId) into a Map that is keyed on RecordTypeId__c. You can therefore remove this if.

        if( caseRecordTypeSet.contains(rec_type)){

This if is also always true. You populate caseRecordTypeSet at the same time you populate SuppourtRecordTypeIdMap, and with the same group of values. If rec_type is in SuppourtRecordTypeIdMap, and we know it is, it's also in caseRecordTypeSet.

            if (c1.Status == status  && c1.Private__c != true){
                caselist1.add(c1);
            }

status is not defined in this code, which is problematic. It suggests either that (a) this code does not compile or (b) you have anonymized it in a way that makes it difficult for us to see what is going on.

In any case, I would put this conditional at the outermost level and invert it. Remember you never need to compare a Boolean explicitly to true or false because it is already a Boolean value.

if (c1.Status != status || c1.Private) continue;

Then your loop just skips all of the evaluation steps for this Case.

        if(caselist1.size() > 0) {
            for(case c : caselist1){

This whole conditional and inner loop is in the wrong place. You should almost never have a loop over some list inside the loop where you are building that list. The result is usually that you insert the same records over and over; other unexpected behavior may occur.

Additionally, you don't need to check the size of a list before you iterate (iterating over a zero-size list does nothing), so you can remove the if entirely.

If this code compiles and runs at all, the code inside your final loop is a clear problem:

                if(caseRecordTypeSet.contains(rec_type)){
                    if(c.RecordTypeId == ST.RecordtypeId__c){
                        if(c.Status == ST.Status__c){  
                            rec_type = c.RecordTypeId;                                               
                            SuppourtCase.Case__c = c.ID;
                            SuppourtCase.Send_mail__c = true;
                        }
                    }

rec_type at the outset here still refers here to the last Case you added to caseList, not to c - the case you're looking at now. The results from this mismatch are likely to be very confusing. You then overwrite rec_type each time through the loop, for no apparent reason since you don't use it again. As a result, rec_type will always be the record type of some Case other than the one you're currently reviewing.

Conclusion

I've seen this code posted across many different questions, so I'd really like to express something clearly. This is a logic issue, and it's not magic - it's basic programming. What you need to do to solve this is sit down and slowly, carefully walk through your logic and your data, and understand how the flow of execution moves through your code based on the input data that you give it.

Working through it manually with a pencil and paper can, honestly, be helpful. Adding System.debug() statements and writing careful unit tests can help you trace what happens, where, and when. But fundamentally, you need to be more rigorous and careful in how you construct your logic.

You can solve this! You've got a basic skeleton that is clearly moving in the right direction. The solution now is not just to fiddle with it and add and remove lines until it works. The solution is to understand what your code is doing and why.

| improve this answer | |

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