'Apex Specialist Challenge 1

I cannot resolve this error.

Closing a Maintenance Request of type 'Routine Maintenance' or 'Repair' did not create of a new Maintenance Request with the correct due date. The challenge is expecting the due date to be calculated using the maintenance cycle defined on the related equipment records. If multiple equipments are used in the maintenance request, choose the shortest maintenance cycle to define the service date.

I'm having a really hard time finishing this challenge. I want to know that which part of my code is wrong, not just answer.

// TriggerHandler
public with sharing class MaintenanceRequestHelper {
    
    public static void updateWorkOrders(Map<Id, Case> oldCases) {
        // TODO: Complete the method to update workorders
        Map<Id, Integer> toGetDueDateMap = new Map<Id, Integer>();
        AggregateResult[] results = [SELECT Id, MIN(Maintenance_Cycle__c) minMC FROM Product2 GROUP BY Id];
        for (AggregateResult ar : results) {
            if (ar != null) {
                toGetDueDateMap.put(ar.Id, Integer.valueOf(ar.get('minMC')));
            }
        }
        List<Case> newCases = new List<Case>();
        for (Case c : oldCases.values()) {
            Case newCase = new Case();
            newCase.Status = 'New';
            newCase.Origin = 'web';
            newCase.Vehicle__c = c.Vehicle__c;
            newCase.ProductId = c.ProductId;
            newCase.Type = 'Routine Maintenance';
            newCase.Subject = 'Routine Maintenance';
            newCase.Date_Reported__c = Date.today();
            newCase.Date_Due__c = (toGetDueDateMap.get(c.Id) != null) ? Date.today().addDays(toGetDueDateMap.get(c.Id)) : Date.today();
            newCases.add(newCase);
        }
        insert newCases;
    }
}

// Trigger
trigger MaintenanceRequest on Case (after update) {
    // ToDo: Call MaintenanceRequestHelper.updateWorkOrders
    Map<Id, Case> caseToEvaluate = new Map<Id, Case>();
    if(Trigger.isAfter && Trigger.isUpdate) {
        for(Case c : Trigger.New) {
            if(c.Status == 'Closed' && (c.Type == 'Repair' || c.Type == 'Routine Maintenance')) {
                caseToEvaluate.put(c.Id, c);
            }
        }
    }
    MaintenanceRequestHelper.updateWorkOrders(caseToEvaluate);
}


Solution 1:[1]

I create correct algoritm to find less maintenance cycle days. Try it.

    newCase.Date_Due__c = Date.today() + suchEarlyDay(newMaintenanceRequest).get(cases.Id);
                newCases.add(newCase);
            }
        }
        if (newCases.size() > 0) {
            insert newCases;
    }
}

    private static Map<Id, Integer> suchEarlyDay(List<Case> cases) {
    Map<Id, Case> caseMap = new Map<Id, Case>(cases);
    Map<Id, Integer> lessDate = new Map<Id, Integer>();
    List<Equipment_Maintenance_Item__c> relatedList = [
            SELECT Maintenance_Request__c,
                    Equipment__r.Maintenance_Cycle__c
            FROM Equipment_Maintenance_Item__c
            WHERE Maintenance_Request__c = :caseMap.keySet()
    ];

    for (Id caseId : caseMap.keySet()) {
        for (Equipment_Maintenance_Item__c equip : relatedList) {
            if (!lessDate.containsKey(caseId) && caseId == equip.Maintenance_Request__c) {
                lessDate.put(caseId, (Integer) equip.Equipment__r.Maintenance_Cycle__c);
            } else if (lessDate.containsKey(caseId) && lessDate.get(caseId) > (Integer) equip.Equipment__r.Maintenance_Cycle__c) {
                lessDate.put(caseId, (Integer) equip.Equipment__r.Maintenance_Cycle__c);
            }
        }
    }
    return lessDate;
}

Solution 2:[2]

This link helped me, so I modified the code like this:

public with sharing class MaintenanceRequestHelper {
public static void updateWorkOrders(List<Case> updWorkOrders, Map<Id,Case> nonUpdCaseMap) {
    Set<Id> validIds = new Set<Id>();
    
    
    For (Case c : updWorkOrders){
        if (nonUpdCaseMap.get(c.Id).Status != 'Closed' && c.Status == 'Closed'){
            if (c.Type == 'Repair' || c.Type == 'Routine Maintenance'){
                validIds.add(c.Id);
                
         
            }
        }
    }
    
    if (!validIds.isEmpty()){
        List<Case> newCases = new List<Case>();
        Map<Id,Case> closedCasesM = new Map<Id,Case>([SELECT Id, Vehicle__c, ProductId, Product.Maintenance_Cycle__c,(SELECT Id,Equipment__c,Quantity__c FROM Equipment_Maintenance_Items__r) 
                                                     FROM Case WHERE Id IN :validIds]);
        Map<Id,Decimal> maintenanceCycles = new Map<ID,Decimal>();
        AggregateResult[] results = [SELECT Maintenance_Request__c, MIN(Equipment__r.Maintenance_Cycle__c)cycle FROM Equipment_Maintenance_Item__c WHERE Maintenance_Request__c IN :ValidIds GROUP BY Maintenance_Request__c];
    
    for (AggregateResult ar : results){ 
        maintenanceCycles.put((Id) ar.get('Maintenance_Request__c'), (Decimal) ar.get('cycle'));
    }
        
        for(Case cc : closedCasesM.values()){
            Case nc = new Case (
                ParentId = cc.Id,
            Status = 'New',
                Subject = 'Routine Maintenance',
                Type = 'Routine Maintenance',
                Vehicle__c = cc.Vehicle__c,
                ProductId =cc.ProductId,
                Origin = 'Web',
                Date_Reported__c = Date.Today()
                
            );
            
            If (maintenanceCycles.containskey(cc.Id)){
                nc.Date_Due__c = Date.today().addDays((Integer) maintenanceCycles.get(cc.Id));
            } else {
                nc.Date_Due__c = Date.today().addDays((Integer) cc.Product.maintenance_Cycle__c);
            }
            
            newCases.add(nc);
        }
        
       insert newCases;
        
       List<Equipment_Maintenance_Item__c> clonedWPs = new List<Equipment_Maintenance_Item__c>();
       for (Case nc : newCases){
            for (Equipment_Maintenance_Item__c wp : closedCasesM.get(nc.ParentId).Equipment_Maintenance_Items__r){
                Equipment_Maintenance_Item__c wpClone = wp.clone();
                wpClone.Maintenance_Request__c = nc.Id;
                ClonedWPs.add(wpClone);
                
            }
        }
        insert ClonedWPs;
    }
}

}

And the trigger:

trigger MaintenanceRequest on Case (before update, after update) {

if(Trigger.isUpdate && Trigger.isAfter){

    MaintenanceRequestHelper.updateWorkOrders(Trigger.New, Trigger.OldMap);

}  }

Solution 3:[3]

Apex Trigger :

trigger MaintenanceRequest on Case (before update, after update) {
    // ToDo: Call MaintenanceRequestHelper.updateWorkOrders
    if(Trigger.isAfter && Trigger.isUpdate){
        MaintenanceRequestHelper.updateWorkOrders(Trigger.new); 
    }
}

Apex Handler:

public with sharing class MaintenanceRequestHelper {
    public static void updateWorkOrders(List<Case> existingMainReq) {
        // TODO: Complete the method to update workorders
        Integer count = 0;
        Map<Id, Integer> toGetDueDateMap = new Map<Id, Integer>();
        Map<Id,Case> newCasesToIdsMap = new Map<Id,Case>();
        List<Case> createNewMainReq = new List<Case>();
        List<Case> caseIdsList = new List<Case>();
        Map<Equipment_Maintenance_Item__c,Id> EquipMainItemsToProdIds = new Map<Equipment_Maintenance_Item__c,Id>();
        
        if(!existingMainReq.isEmpty()){
            for(Case cc : existingMainReq){
                if((cc.Type == 'Repair' || cc.Type == 'Routine Maintenance') && cc.Status == 'Closed'){
                    caseIdsList.add(cc);   
                }
            }    
        }
        List<Equipment_Maintenance_Item__c> equipMainList = [Select id,Equipment__c,Maintenance_Request__c from Equipment_Maintenance_Item__c where Maintenance_Request__c IN : caseIdsList];
        if(!equipMainList.isEmpty()){
            for(Equipment_Maintenance_Item__c equipMainn : equipMainList){
                EquipMainItemsToProdIds.put(equipMainn,equipMainn.Equipment__c);
                system.debug(EquipMainItemsToProdIds.size());
                if(EquipMainItemsToProdIds.size() > 1){
                    count = EquipMainItemsToProdIds.size();
                }
            }  
        }
      List<Equipment_Maintenance_Item__c> EMIList = [Select Equipment__r.Maintenance_Cycle__c,Equipment__c from Equipment_Maintenance_Item__c where Equipment__r.Id IN :EquipMainItemsToProdIds.values() AND Maintenance_Request__c IN:caseIdsList order By Equipment__r.Maintenance_Cycle__c ASC limit 1];
            for(Equipment_Maintenance_Item__c equip : EMIList){
                toGetDueDateMap.put(equip.Id,Integer.valueOf(equip.Equipment__r.Maintenance_Cycle__c));  
                for(Case c : caseIdsList){
                    Case mainRe = new Case();
                    mainRe.Vehicle__c = c.Vehicle__c;
                    mainRe.status = 'New';
                    mainRe.Type = 'Routine Maintenance';
                    mainRe.Subject = 'New Main Request For Vehicle for Apex Specialist';
                    mainRe.Date_Reported__c = date.today();
                    if(count > 1){
                        mainRe.Date_Due__c = Date.today().addDays(toGetDueDateMap.get(equip.Id));
                    }
                    else{
                        mainRe.Date_Due__c = Date.today();
                    }
                    createNewMainReq.add(mainRe);
                    newCasesToIdsMap.put(c.Id,mainRe);
                }  
               insert createNewMainReq; 
                if(caseIdsList.size()>0 && newCasesToIdsMap.size()>0){
                        cloneEquipItems(caseIdsList,newCasesToIdsMap);
                    }
            }
    }
    public static void cloneEquipItems(List<case> closedCaseRecords, Map<Id,case> newCreatedCasesMapp){
        List<Equipment_Maintenance_Item__c> newEquipItems = new List<Equipment_Maintenance_Item__c>();
        try{
            if(!closedCaseRecords.isEmpty() && newCreatedCasesMapp.size()>0){
                List<Equipment_Maintenance_Item__c> oldEquipItems = [SELECT Equipment__c, Maintenance_Request__c, Quantity__c,Maintenance_Request__r.Id
                                                                     FROM Equipment_Maintenance_Item__c
                                                                     WHERE  Maintenance_Request__c IN :closedCaseRecords];
                
                for(Equipment_Maintenance_Item__c equipItem : oldEquipItems) {
                    
                    Equipment_Maintenance_Item__c newItem = equipItem.clone(false, true, false, false);
                    newItem.Maintenance_Request__c = newCreatedCasesMapp.get(equipItem.Maintenance_Request__c).id;
                    newEquipItems.add(newItem);
                }
                insert newEquipItems;
            }
        }
        catch(Exception e){
            System.debug('Exception is'+ e);
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sebrunt
Solution 2 talkinghead
Solution 3 Aror