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
StaciStaci 

Duplicate id in list error

What its supposed to do:
When a change record is closed, it pulls a list of related cases.  You can check a box next to the cases you want closed with this change record.  It should then change the Status to Closed - Resolved.  For the cases that aren't checked, I want the Status to change to Pending - RCA.  I get the pop up with the list of cases to be checked or not, but upon save I get Duplicate id in list error with the ID of one of the cases I didn't check.  Please help!



public class CW_wrapperClassController {
String[] defects = new String[]{};
    public CW_wrapperClassController() {
    }
private final Change__c chg;
    public CW_wrapperClassController(ApexPages.StandardController controller) {
     chg = (Change__c) controller.getRecord();
     chg.StatusChange__c = 'Completed';
     }

    //Our collection of the class/wrapper objects cCase(just a name)
    public List<cCase> caseList {get; set;}

    //This method uses a simple SOQL query to return a List of Cases associated with this change record
    public List<cCase> getCases() {
         if(caseList == null) {
           caseList=new List<cCase>();
           }
             List<ID> caseIDS = new List<ID>();
             for(Case_Change_Association__c CCA:[select Case__c from Case_Change_Association__c where Change__c=:chg.ID]){
             caseIDS.add(CCA.Case__c);
             }
             for(Case c:[select CaseNumber, Defect_Type_Multi__c from Case Where Status != 'Closed - Resolved' AND ID in:caseIDS]){
             caseList.add(new cCase(c));
             }
             return caseList;
     }
        public List<SelectOption> getItems() {
            List<SelectOption> options = new List<SelectOption>();
            options.add(new SelectOption('HARDWARE','Hardware'));
            options.add(new SelectOption('SOFTWARE','Software'));
            options.add(new SelectOption('INFRASTRUCTURE','Ingrastructure'));
            options.add(new SelectOption('CONFIGURATION','Configuration'));
            options.add(new SelectOption('MINE MODEL','Mine Model'));
            options.add(new SelectOption('TRAINING','Training'));
            options.add(new SelectOption('DOCUMENTATION','Documentation'));
            options.add(new SelectOption('PROCESS','Process'));
            options.add(new SelectOption('3RD PARTY SERVICE PROVIDER','3rd Party Service Provider'));
            return options;
        }
    public PageReference processSelected() {

        //We create a new list of Cases that we be populated only with Cases if they are selected
        List<Case> selectedCases = new List<Case>();
        List<Case> unselectedCases = new List<Case>();
        List<Case> selectedcasesToUpdate = new List<Case>();
        List<Case> nonselectedcasesToUpdate = new List<Case>();

        //We will cycle through our list of cCase and will check to see if the selected property is set to true, if it is we add the Case to the selectedCases list
        for(cCase cCs: getCases()) {
            if(cCS.selected == true) {
                selectedCases.add(cCS.cs);
            }
            //Adding a list for unselected cases to be processed
            if(cCS.selected == false){
                unselectedCases.add(cCS.cs);
                }
            }
       
        // Now we have our list of selected cases and can perform any type of logic we want, sending emails, updating a field on the Contact, etc
        //System.debug('These are the selected Cases...');
        for(Case cs: selectedCases) {
           cs.Status = 'Closed - Resolved';
           cs.Change_Closing_Comments__c = chg.Closing_Comments__c;
           if(cs.Incident_Resolved_Internal__c!=NULL)
           {
              }else{
              cs.Incident_Resolved_Internal__c = chg.Implementation_End_Date_Time__c;
           }    
           //update(cs);  
           selectedcasesToUpdate.add(cs);
        }
        //Processing unselected cases.
        for(Case csun: unselectedCases){
            csun.Status = 'Pending - RCA';
            //csun.OwnerId = chg.Change_Implementer__c;
            //update(csun);
            nonselectedcasesToUpdate.add(csun);
           
        }
        //Updating a list of cases, instead of each case within a FOR, for bulkification.
       
        update selectedcasesToUpdate;
        //Updating the change record, since the status is already set as "completed" above.
        update chg;
        update nonselectedcasesToUpdate;
       
        caseList=null; // we need this line if we performed a write operation  because getCases gets a fresh list now
        PageReference redirect = new PageReference('/'+chg.ID);
        redirect.setredirect(true);
        return redirect;
            }
    // This is our wrapper/container class. A container class is a class, a data structure, or an abstract data type whose instances are collections of other objects. In this example a wrapper class contains both the standard salesforce object Case and a Boolean value
    public class cCase {
        public Case cs {get; set;}
        public Boolean selected {get; set;}

        //This is the contructor method. When we create a new cCase object we pass a Case that is set to the con property. We also set the selected value to false
        public cCase (Case c) {
            cs = c;
            selected = false;
        }    }
   public String[] getDefect() {
    return defects;
    }
    
    public void setDefect(String[] defects) {
            this.defects = defects;
        }}
kcpluspluskcplusplus
I'm not sure yet where you are catching the duplicate id, you may want to consider using a set to prevent duplication. i.e using the Set contains method. 

However, I would recommend a refactor of your logic, that might catch the issue itself. 

public class CW_wrapperClassController {
String[] defects = new String[]{};
    public CW_wrapperClassController() {
    }
private final Change__c chg;
    public CW_wrapperClassController(ApexPages.StandardController controller) {
     chg = (Change__c) controller.getRecord();
     chg.StatusChange__c = 'Completed';
     }

    //Our collection of the class/wrapper objects cCase(just a name)
    public List<cCase> caseList {get; set;}

    //This method uses a simple SOQL query to return a List of Cases associated with this change record
    public List<cCase> getCases() {
         if(caseList == null) {
           caseList=new List<cCase>();
           }
             List<ID> caseIDS = new List<ID>();
             for(Case_Change_Association__c CCA:[select Case__c from Case_Change_Association__c where Change__c=:chg.ID]){
             caseIDS.add(CCA.Case__c);
             }
             for(Case c:[select CaseNumber, Defect_Type_Multi__c from Case Where Status != 'Closed - Resolved' AND ID in:caseIDS]){
             caseList.add(new cCase(c));
             }
             return caseList;
     }
        public List<SelectOption> getItems() {
            List<SelectOption> options = new List<SelectOption>();
            options.add(new SelectOption('HARDWARE','Hardware'));
            options.add(new SelectOption('SOFTWARE','Software'));
            options.add(new SelectOption('INFRASTRUCTURE','Ingrastructure'));
            options.add(new SelectOption('CONFIGURATION','Configuration'));
            options.add(new SelectOption('MINE MODEL','Mine Model'));
            options.add(new SelectOption('TRAINING','Training'));
            options.add(new SelectOption('DOCUMENTATION','Documentation'));
            options.add(new SelectOption('PROCESS','Process'));
            options.add(new SelectOption('3RD PARTY SERVICE PROVIDER','3rd Party Service Provider'));
            return options;
        }
    public PageReference processSelected() {

        //We create a new list of Cases that we be populated only with Cases if they are selected
        List<Case> update_cases = new List<Case>();
        Set<Id> case_ids = new Set<Id>();
        //We will cycle through our list of cCase and will check to see if the selected property is set to true, if it is we add the Case to the selectedCases list
        for(cCase cCs: getCases()) {
            Case cs = cCs.cs;
            //this should help us dedupe
            if(!case_ids.contains(cs.Id)){
                if(cCS.selected == true) {
                    cs.Status = 'Closed - Resolved';
                    cs.Change_Closing_Comments__c = chg.Closing_Comments__c;
                    //changed this to be == null, to remove the unused if block
                    if(cs.Incident_Resolved_Internal__c==NULL){
                      cs.Incident_Resolved_Internal__c = chg.Implementation_End_Date_Time__c;
                    }
                }
                //Adding a list for unselected cases to be processed
                if(cCS.selected == false){
                    cs.Status = 'Pending - RCA';
                    //csun.OwnerId = chg.Change_Implementer__c;
                    //update(csun);
                }
                update_cases.add(cs)
                case_ids.add(cs.Id);
            }
        }
      
        update chg;
      
        caseList=null; // we need this line if we performed a write operation  because getCases gets a fresh list now
        PageReference redirect = new PageReference('/'+chg.ID);
        redirect.setredirect(true);
        return redirect;
            }
    // This is our wrapper/container class. A container class is a class, a data structure, or an abstract data type whose instances are collections of other objects. In this example a wrapper class contains both the standard salesforce object Case and a Boolean value
    public class cCase {
        public Case cs {get; set;}
        public Boolean selected {get; set;}

        //This is the contructor method. When we create a new cCase object we pass a Case that is set to the con property. We also set the selected value to false
        public cCase (Case c) {
            cs = c;
            selected = false;
        }    }
   public String[] getDefect() {
    return defects;
    }
   
    public void setDefect(String[] defects) {
            this.defects = defects;
        }}
StaciStaci
@kcplusplus unfortunately this isn't updating anything now.  Any other thoughts?