salesforceapexsalesforce-service-cloudsalesforce-communities

Trailhead Superbadge Logic to create Junction Object


I have a challenge to complete. The requirement is automate record creation of a new Case record(renamed maintenance request). When an existing maintenance request(Case record) of type Repair or Routine Maintenance is closed, create a new maintenance request(Case record) for a future routine checkup. This new maintenance request is tied to the same Vehicle and Equipment(Product2- Standard Object renamed) Records as the original closed request. There is a logic on the due date field. It should have the min date compared to all the maintenance cycle of the equipment record related to the maintenance request.

I separated the logic in a helper class for the trigger. I believe the helper class code logic for 'Equipment Maintenance Item' record creation is not the right approach but trailhead already accepted it and provided me 500 points. Please help me find the right approach for the new 'Equipment Maintenance Item' record creation logic.

(The 'Equipment Maintenance Item' object is a Junction Object) image

2 standard objects are used: Maintenance Request (renamed Case) and Equipment (renamed Product)

2 custom objects are used: Vehicle and Equipment Maintenance Item

Trigger:

trigger MaintenanceRequest on Case (before update, after update) {
if(Trigger.isAfter){
    MaintenanceRequestHelper.updateWorkOrders(Trigger.New);
}} 

Helper Class:

public with sharing class MaintenanceRequestHelper {

public static void updateWorkOrders(List<Case> CaseList) {
    integer i=0;
    List<Case> NewCaseList = new List<Case>();
    List<Equipment_Maintenance_Item__c> eList = [SELECT Id,Maintenance_Request__c,Equipment__c,Quantity__c 
                                                FROM Equipment_Maintenance_Item__c 
                                                WHERE Maintenance_Request__c IN: CaseList];
    List<Aggregateresult> mindue = new List<Aggregateresult>([SELECT MIN(Equipment__r.Maintenance_Cycle__c)MinimumValue 
                                                              FROM Equipment_Maintenance_Item__c WHERE Maintenance_Request__c IN: CaseList]);
    integer k=0;
    List<Equipment_Maintenance_Item__c> newEmi = new List<Equipment_Maintenance_Item__c>();
    for(Case c : CaseList){
        if(c.Status == 'Closed' && (c.type =='Repair' || c.type =='Routine Maintenance')){
            Case c1 = new Case(
            Status = 'New',
            Vehicle__c = c.Vehicle__c,
            Type = 'Routine Maintenance',
            Subject = 'Routine Checkup',
            Date_Reported__c = Date.today(),
            Product__c = c.Product__c,
            AccountId = c.AccountId,
            ContactId = c.ContactId,
            Origin = c.Origin
            //Date_Due__c = Date.today()
            );
            NewCaseList.add(c1);
            for(Equipment_Maintenance_Item__c emi : eList){
               if(c.Id == emi.Maintenance_Request__c){
                 newEmi.add(new Equipment_Maintenance_Item__c(
                              Equipment__c = emi.Equipment__c,
                              Maintenance_Request__c = c.Id,
                              Quantity__c = emi.Quantity__c));
                  }
             }
             for(Aggregateresult r:mindue){          
                if(r.get('MinimumValue')!=NULL){
                   NewCaseList[i].Date_Due__c=system.today()+integer.valueof(r.get('MinimumValue'));
                }
             i++;
             }
        }
        
    }
    if(NewCaseList.size()>0){
        insert NewCaseList;     
    }

    for(Case c2: NewCaseList){
        for(Equipment_Maintenance_Item__c emi2 : newEmi){
            emi2.Maintenance_Request__c = c2.id;
       }
    }
          
     insert newEmi;   
}

}


Solution

  • Your Code is correct but not bulkified. It will work for a single record and it will fail in case a bunch of records closed at the same time. I have solved it by creating one field on the Case object which will store cloned Case Id i.e. the old case from which the new case has been created.

    Please refer code sample below:

        trigger MaintenanceRequest on Case (before update, after update) {
            //ToDo: Call MaintenanceRequestHelper.updateWorkOrders
            if(trigger.isAfter){
                MaintenanceRequestHelper.updateWorkOrders(trigger.new);    
            }
        }
    
    public with sharing class MaintenanceRequestHelper {
        
        public static void updateWorkOrders(List<Case> newList) {
            // TODO: Complete the method to update workorders
            List<Case> CreateMaintReqLst = new List<Case>();
            Set<Id> caseIdsSet = new Set<Id>();
            List<Equipment_Maintenance_Item__c> newEMI = new List<Equipment_Maintenance_Item__c>();
            for (Case caseRec : newList)
            {
                if(caseRec.Status == 'Closed' &&
                   (caseRec.Type =='Repair' || caseRec.Type =='Routine Maintenance'))
                {
                    caseIdsSet.add(caseRec.Id);    
                }
            }
            List<Case> CaseList = [SELECT Id,Type,Status,Vehicle__c,Subject,Date_Reported__c,Date_Due__c,ProductId,Product__c,
                                   (select Id,Maintenance_Cycle__c,Equipment__c,Quantity__c FROM Equipment_Maintenance_Items__r)
                                   FROM Case
                                   WHERE Id in:caseIdsSet];        
            
            for(Case caseRec:CaseList){
                Integer minMaintCycle = 0;
                List<Equipment_Maintenance_Item__c> EqpMaintList = caseRec.Equipment_Maintenance_Items__r;
                if(EqpMaintList.size()>0){
                    for(Equipment_Maintenance_Item__c EquipMaint:EqpMaintList){
                        newEMI.add(new Equipment_Maintenance_Item__c(
                            Equipment__c = EquipMaint.Equipment__c,
                            Maintenance_Request__c = caseRec.Id,
                            Quantity__c = EquipMaint.Quantity__c));
                        if(Integer.valueOf(EquipMaint.Maintenance_Cycle__c) < minMaintCycle || minMaintCycle == 0){
                            minMaintCycle =Integer.valueOf(EquipMaint.Maintenance_Cycle__c);
                        }       
                    }
                }
                Case newCase = new Case();
                newCase.Type = 'Routine Maintenance';
                newCase.Status = 'New';
                newCase.Vehicle__c = caseRec.Vehicle__c;
                newCase.Subject =  String.isBlank(caseRec.Subject) ? 'Routine Maintenance Request' : caseRec.Subject;
                newCase.Date_Reported__c = Date.today();
                newCase.Date_Due__c = Date.today().addDays(minMaintCycle);
                newCase.ProductId = caseRec.ProductId;
                newCase.Product__c = caseRec.Product__c;
                newCase.Cloned_Closed_Case_Id__c = caseRec.Id;
                CreateMaintReqLst.add(newCase);
            }
            
            if(CreateMaintReqLst.size()>0){
                Database.insert(CreateMaintReqLst);    
            }
            
            for(Case c2: CreateMaintReqLst){
                for(Equipment_Maintenance_Item__c emi2 : newEmi){
                    if(c2.Cloned_Closed_Case_Id__c == emi2.Maintenance_Request__c){
                        emi2.Maintenance_Request__c = c2.id;    
                    }
                }
            }
            
            if(newEmi.size()>0){
                Database.insert(newEmi);    
            }     
        }        
    }