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
Dheeraj SharmaDheeraj Sharma 

Apex Super badge

I unlocked the apex super badge, but In its very first step, I got stuck. I am not able to complete the very first step. I have created a trigger and helper and I have tested the flow by myself all works well. But still, I am getting below error in trailhead.
User-added image
I have created a trigger on the case.

trigger GenerateMaintenanceCase on Case (before update) {
        ITriggerManager trgrManager = new CaseTriggerHandler();
        TriggerHandler.InvoceHandler(trgrManager);
}

below is the Case trigger handler


public class CaseTriggerHandler implements ITriggerManager{
    
    
    public void onBeforeInsert(List<sObject> newObjLst,Map<Id,sObject> newObjMap){ }
    
    public void onBeforeUpdate(List<sObject> newObj,List<sObject> oldObj,Map<Id,sObject> newMap, Map<Id,sObject> oldMap){
        List<Case> lstOfNewCase = (List<Case>) newObj;
        
        
        List<Case> lstOfCaseToProcess = new List<Case>();
        List<Case> lstOfCaseGetCreated = new List<Case>(); 
        
        for(Case newCase:lstOfNewCase){
            if(''+oldMap.get(newCase.Id).get('Status') != ''+newMap.get(newCase.Id).get('Status') && newMap.get(newCase.Id).get('Status') =='Closed'){
                 lstOfCaseToProcess.add(newCase);
            }
        }
        
        Map<Id,Integer> mapOfLowestWODate = new Map<Id,Integer>();
        if(lstOfCaseToProcess!=null && lstOfCaseToProcess.size()>0 ){
             List<Case> lstOfCase = [SELECT id,Date_Due__c, Vehicle__c,Equipment__c,
                                    (SELECT id,Equipment__r.Maintenance_Cycle__c FROM Work_Parts__r) 
                                     FROM Case 
                                     WHERE Id 
                                     IN :lstOfCaseToProcess];
                                     
             for(Case caseToUpdate: lstOfCase){
                Integer lowest =0;
                for(Work_Part__c workPart: caseToUpdate.Work_Parts__r){
                    if(lowest==0 || lowest>workPart.Equipment__r.Maintenance_Cycle__c){
                       lowest = Integer.valueOf(workPart.Equipment__r.Maintenance_Cycle__c!=null?workPart.Equipment__r.Maintenance_Cycle__c:0);  
                    }
                }
                mapOfLowestWODate.put(caseToUpdate.Id,lowest); 
                Case myCase = new Case();
                //myCase.recordTypeId = mapOfRecordTypeNameToId.get('Routine Maintenance');
                myCase.Type ='Routine Maintenance';
                myCase.subject='As a part of maintenance request';
                myCase.Vehicle__c = caseToUpdate.Vehicle__c;
                myCase.Equipment__c = caseToUpdate.Equipment__c;
                myCase.Date_Reported__c = System.today();
                myCase.Date_Due__c= System.Today()+lowest;
                lstOfCaseGetCreated.add(myCase);
             }
         }
        if(lstOfCaseGetCreated!=null && lstOfCaseGetCreated.size()>0 ){
            insert lstOfCaseGetCreated;
        }
        
    }
    
    public void onAfterInsert(List<sObject> newObj,Map<Id,sObject> newObjMap){}
    
    public void onAfterUpdate(List<sObject> newObj,List<sObject> oldObj,Map<Id,sObject> newMap, Map<Id,sObject> oldMap){}

}

below is the trigger handler

Public class TriggerHandler{

    public static void InvoceHandler(ITriggerManager TriggerMng){
        
        if(Trigger.isBefore){
            
            if(Trigger.isInsert){
                TriggerMng.onBeforeInsert(Trigger.new,Trigger.newMap);
            }
            
            if(Trigger.isUpdate){
               TriggerMng.onBeforeUpdate(Trigger.new,Trigger.old,Trigger.newMap,Trigger.oldMap);                
            }
        }
        if(Trigger.isAfter){
            if(Trigger.isInsert){
                TriggerMng.onAfterInsert(Trigger.new,Trigger.newMap);
            }
            
            if(Trigger.isUpdate){
               TriggerMng.onAfterUpdate(Trigger.new,Trigger.old,Trigger.newMap,Trigger.oldMap);                
            }
        }
    }
}

ITriggerManager  is my interface:

public interface ITriggerManager{
    void onBeforeInsert(List<sObject> newObjLst,Map<Id,sObject> newObjMap);
    void onBeforeUpdate(List<sObject> newObj,List<sObject> oldObj,Map<Id,sObject> newMap, Map<Id,sObject> oldMap);
    void onAfterInsert(List<sObject> newObj,Map<Id,sObject> newObjMap);
    void onAfterUpdate(List<sObject> newObj,List<sObject> oldObj,Map<Id,sObject> newMap, Map<Id,sObject> oldMap);
}


Please help to understand this error and plz let me know if there is an issue with my code.

Thanks,
 
RakeshRakesh (Salesforce Developers) 
HI Dheeraj Sharma,

Pre-work and Notes: Standard Objects:
  1. Maintenance Request (renamed Case) — Service requests for broken vehicles, malfunctions, and routine maintenance.
  2. Click Setup – Build – Customize – Tab names and Labels – rename Tabs and Labels–Click on Edit Case Obj – Now Change the Names
  3. Equipment (renamed Product) — Items in the warehouse used to fix or maintain RVs. Repair parts have a flag indicating that they are for repair.
  4. Click Setup – Build – Customize – Tab names and Labels – rename Tabs and Labels – Click on EditProductObj – Now Change the names
Custom Objects:
  1. These Two Objects are coming to Installed package. Vehicle — Vehicles in HowWeRoll’s rental fleet. These records contain all stock parts that will eventually need replacement or maintenance.
  2. WorkPart — Equipment used for a maintenance request.
Entity Diagram:
User-added image
Schema Builder Diagram In Your Org:
User-added image

Now tackle thisSuper badge challenges!
Automate Record Creation:
Install the unmanaged package for the schema and stubs for Apex classes and triggers. Rename cases and products to match the HowWeRoll schema, and assign all profiles to the custom HowWeRoll page layouts for those objects. Use the included package content to automatically create a Routine Maintenance request every time a maintenance request of type Repair or Routine Maintenance is updated to Closed. Follow the specifications and naming conventions outlined in the business requirements.

Note: Before you start, Please refer the Automate Maintenance Requests. 

Open MaintenanceRequestHelperClass. Don’t create this class, will get this class by installing unmanaged package. Use the below code:
public class MaintenanceRequestHelper {

public static void updateWorkOrders(Map<Id, Case>applicableCases){

Map<Id, Integer>mapProduct = new Map<Id, Integer>();
List<Case>newCases = new List<Case>();

List<Product2>listProduct = [select Id, Maintenance_Cycle__c from Product2];
for (Product2 p :listProduct) {
if (p != null) {
if(p.Maintenance_Cycle__c != null){
mapProduct.put(p.Id, Integer.valueOf(p.Maintenance_Cycle__c));
}
}
}

for(Case a: applicableCases.values()){
Case newCase = new Case();
newCase.Vehicle__c = a.Vehicle__c;
newCase.Equipment__c = a.Equipment__c;
newCase.Type = 'Routine Maintenance';
newCase.Subject = String.isBlank(a.Subject) ? 'Routine Maintenance Request' :a.Subject;
newCase.Date_Reported__c = Date.today();
newCase.Status = 'New';
newCase.Product__c = a.Product__c;
newCase.AccountId = a.AccountId;
newCase.ContactId = a.ContactId;
newCase.AssetId = a.AssetId;
newCase.Origin = a.Origin;
newCase.Reason = a.Reason;
newCase.Date_Due__c=  (mapProduct.get(a.Id) != null) ? (Date.today().addDays(Integer.valueOf(mapProduct.get(a.Id)))) : (Date.today());
newCases.add(newCase);
}
if(newCases.size() > 0){
insert newCases;
}
}
}
Open MaintenanceRequestTrigger: Use the below code
trigger MaintenanceRequest on Case (before update, after update) {        
    Map<Id,Case>applicableCases = new Map<Id,Case>();    
if(Trigger.isUpdate){
if(Trigger.isAfter){
for(Case a: Trigger.new){
                if (a.IsClosed&& (a.Type.equals('Repair') || a.Type.equals('Routine Maintenance'))){
applicableCases.put(a.Id, a);
                }
            }
            // call MaintenanceRequestHelper.updateWorkOrders	
MaintenanceRequestHelper.updateWorkOrders(applicableCases);   
        }
    } 
}
Check the functionality, what you did then verify the challenge, you will be verified, If not please let me know what kind of issue you are facing send the screenshots and error message. Then accordingly I can help you.

Happy to help you further!

Hope this helps you!
Please mark it as solved, If this reply was helpful.

Thanks,
Rakesh
suneel sunkarasuneel sunkara
Challenge Not yet complete... here's what's wrong: 
There was an unexpected error in your org which is preventing this assessment check from completing: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Validation Formula "RecurringChargeTypeMustHaveBillingType" Invalid (Field 00N6F00000HyvBc is inaccessible. Please review all fields referenced by the formula. Context: common.config.entity.ValidationFormulaContext): []


Can anyone help me get around this problem??