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
Michael LauMichael Lau 

Apex Specialist Superbadge not passing?

Good day guys, still learning and quite new, but I was just wondering what's wrong with my code.. when I run it it seems to do what is required by the challenge, but it's returning an error that says closing a routine maintenance type maintenance request is not creating a new maintenance request with same vehicle, but when I ran my code it did? Here's my code...
 
trigger:
trigger MaintenanceRequest on Case (before update, after update) {
    // ToDo: Call MaintenanceRequestHelper.updateWorkOrders
    if(Trigger.isUpdate) {
        if (Trigger.isAfter) {
            MaintenanceRequestHelper.updateWorkOrders(Trigger.New);
        }
    }
}

apex:
public with sharing class MaintenanceRequestHelper {
    public static void updateWorkOrders(List<Case> updatedCase) {

        for(Case a : updatedCase) {
            if (a.Status == 'Closed' && (a.Type == 'Repair' || a.Type == 'Routine Maintenance')) {
                
                helperBatch myBatchObject = new helperBatch(updatedCase);
                Id batchId = Database.executeBatch(myBatchObject);
            }
        }
        
    }          
}

helper apex batch:
public class helperBatch implements
Database.Batchable<sObject>, Database.Stateful {
    // instance member to retain state across transactions
    public Integer recordsProcessed = 0;
    public List<Case> updatedCase = new List<Case>();
    
    public helperBatch(List<Case> temp) {
        updatedCase = temp;
    }
    
    public Database.QueryLocator start(Database.BatchableContext bc) {
        system.debug('yo: ' + updatedCase);
        return Database.getQueryLocator(
            'SELECT Equipment__c, Name FROM Equipment_Maintenance_Item__c WHERE Maintenance_Request__c IN :updatedCase'
        );
    }
    public void execute(Database.BatchableContext bc, List<Equipment_Maintenance_Item__c> scope){
        // process each batch of records
        Date dueDate = null;
        List<Product2> cycle = new List<Product2>(); 
        List<id> equipments = new List<id>();
        List<Equipment_Maintenance_Item__c> finalEquipment = new List<Equipment_Maintenance_Item__c>();
        set<Id> equipId = new Set<Id>();
        Vehicle__c vehicle = new Vehicle__c();
        
        for(Case a : updatedCase) {
            vehicle.id = a.Vehicle__c;    
            /*
if (a.Vehicle__c != '') {
vehicle.id = a.Vehicle__c;    
} 
else {
vehicle.id = '';
}*/
        }
        
        system.debug('before count');
        
        List<Equipment_Maintenance_Item__c> listEquipments = new List<Equipment_Maintenance_Item__c>([SELECT Equipment__c, Name, Quantity__c FROM Equipment_Maintenance_Item__c WHERE Maintenance_Request__c IN :updatedCase]);
        system.debug('list: ' + listEquipments);
        Integer x = listEquipments.size();        
        
        system.debug('equip size: ' + x);
        
        Case newCase = new Case(
            Type = 'Routine Maintenance',
            Vehicle__c = updatedCase[0].Vehicle__c,
            //Vehicle__c = vehicle.Id,
            Subject = updatedCase[0].Subject,
            Date_Reported__c = Date.today(),
            Status = 'Open',
            Origin = 'Web'
        );
        
        system.debug('id: ' + updatedCase[0].Id);
        
        system.debug('before upsert');
        upsert newCase;  
        system.debug('after upsert');
        if (x > 0) {
            for (Integer i = 0; i < x; i++) {
                
                equipments.add(listEquipments[i].Equipment__c);
                
                finalEquipment.add(new Equipment_Maintenance_Item__c(
                    Equipment__c = equipments[i],
                    Maintenance_Request__c = newCase.Id,
                    Quantity__c = listEquipments[i].Quantity__c)
                                  );
                
                equipId.add(equipments[i]);
            }
            
            upsert finalEquipment;
            
        }
        
        cycle = [select Maintenance_Cycle__c from Product2 where Product2.id in :equipId order by Maintenance_Cycle__c ASC];
        
        
        
        system.debug('cycle size: ' + cycle.size());
        dueDate = Date.today();
        if(cycle.size() > 0) {
            dueDate = dueDate.addDays(Integer.valueOf(cycle[0].Maintenance_Cycle__c));    
        }
        else {
            dueDate = Date.today();
        }
        
        newCase.Date_Due__c = dueDate;
        update newCase;
        system.debug(newCase);
        system.debug(finalEquipment);
    }
    
    public void finish(Database.BatchableContext bc){
        System.debug(recordsProcessed + ' records processed. Shazam!');
        AsyncApexJob job = [SELECT Id, Status, NumberOfErrors,
                            JobItemsProcessed,
                            TotalJobItems, CreatedBy.Email
                            FROM AsyncApexJob
                            WHERE Id = :bc.getJobId()];
        
        system.debug('job: ' + job);
    }
}

Thanks in advance.. what am I doing wrong?
Nagarjuna ParalaNagarjuna Parala
Hi @Michael Lau,

Thank you reaching out. Please find the updated code for your concern. For your actual logic to excute you should derive that in the triiger itself

Trigger:

trigger MaintenanceRequest on Case (before update, after update) {
    // call MaintenanceRequestHelper.updateWorkOrders
    if(Trigger.isUpdate && Trigger.isAfter) {
        List<Case> newCaseList = new List<Case>();
        Set<Case> closedCase = new Set<Case>(); 
        for(Case ca: Trigger.new) {
            if(ca.Status == 'Closed' && (ca.Type == 'Repair' || ca.Type == 'Routine Maintenance')) {
                closedCase.add(ca);        
            }
        }
        List<Work_Part__c> workPartList = [SELECT Id,Equipment__r.Maintenance_Cycle__c,Maintenance_Request__c from Work_Part__c where Maintenance_Request__c in :closedCase];
        System.debug(workPartList);
        MaintenanceRequestHelper.updateWorkOrders(closedCase, workPartList);
    }  
}

Handler Class :

public class MaintenanceRequestHelper {
    public static void updateWorkOrders(Set<Case> closedCase, List<Work_Part__c> workPartList){
        List<Case> newCaseList = new List<Case>();
        Map<String, Decimal> mapOfCycle = getMapOfCycle(workPartList);
        for(Case ca : closedCase) {
                Case newCase = new Case();
                newCase.Status = 'New';
                newCase.Vehicle__c = ca.Vehicle__c;
                newCase.Type = 'Routine Maintenance'; 
                newCase.Subject = 'Routine Maintenance '+Date.today();
                newCase.Equipment__c = ca.Equipment__c;
                newCase.Date_Reported__c = Date.today();
                newCase.Date_Due__c = (mapOfCycle.containsKey(ca.Id) == true) ? Date.today().addDays(Integer.valueOf(mapOfCycle.get(ca.Id))) : null;
                newCaseList.add(newCase);
        }
         if(newCaseList.size()>0) {
            insert newCaseList;
        }
    }    
    private static Map<String,Decimal> getMapOfCycle(List<Work_Part__c> workPartList){
         Map<String, Decimal> mapOfCycle = new Map<String,Decimal>();
          for(Work_Part__c wp : workPartList){
            system.debug('~~'+wp.Equipment__r.Maintenance_Cycle__c);
            if(wp.Equipment__r.Maintenance_Cycle__c != null) {
                if(mapOfCycle.containsKey(wp.Maintenance_Request__c)) {
                    Decimal cyc = mapOfCycle.get(wp.Maintenance_Request__c);
                    if(cyc > wp.Equipment__r.Maintenance_Cycle__c) {
                        mapOfCycle.put(wp.Maintenance_Request__c, wp.Equipment__r.Maintenance_Cycle__c);
                    }
                }
                else {
                    mapOfCycle.put(wp.Maintenance_Request__c, wp.Equipment__r.Maintenance_Cycle__c);
                }
            }
        }
        return mapOfCycle;
    }
}

Having said that you don't need any batch to process this. You can still stick to your handler class to complete this requirement. U hope this will resolve your issue. Please do let me know if you need any further information. Have a great day ahead!

Thank you
Nagarjuna
Michael LauMichael Lau
Hi thank you for the reply. May I ask where the Work_Part__c is located? I tried looking for a custom object with that name in object manager but failed to find one..Did you mean the Equipment_Maintenance_Item__c?
Michael LauMichael Lau
And you don't have logic to copy the equipment list of the closed case to the new one, assigning Equipment__c doesn't do it... There might be something wrong with your code..
Michael LauMichael Lau
It's ok, I filled in some code to polish the logic, passed the test. Thank you for your help sir!