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
Edgar MoranEdgar Moran 

Superbadges - Apex Specialist (The 'MaintenanceRequest' trigger does not appear to be handling bulk operations correctly)

Hi guys, I'm almost finished with the test to get tge Apex Specialist SuperBadge, I attempt to validate the "Test automation logic" but I can't really see what is my error or why is not passing. This is the message I get:

"Challenge Not yet complete... here's what's wrong: 
The 'MaintenanceRequest' trigger does not appear to be handling bulk operations correctly. For the positive use case of inserting and updating more than 200 records, it did not produce the expected outcome."

and here is my code:

Trigger:
 
trigger MaintenanceRequest on Case (after update) {
	
	//List<Case> casesToEvaluate = new List<Case>();
	Map<Id, Case> casesToEvaluate = new Map<Id, Case>();

	if(Trigger.isAfter && Trigger.isUpdate){
		for(Case maintenance:Trigger.new){
			if((maintenance.Type.contains('Repair') || maintenance.Type.contains('Routine Maintenance')) && maintenance.Status == 'Closed'){
				casesToEvaluate.put(maintenance.Id,maintenance);
			}
		}		
	}
	MaintenanceRequestHelper.updateWorkOrders(casesToEvaluate);
}

Here's the class:
 
public class MaintenanceRequestHelper {

	public static void updateWorkOrders(Map<Id, Case>  cases){
		List<Case> maintenance_routineList = new List<Case>();

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

		System.debug('### product: '+mapProduct);

		for(Case maintenance:cases.values()){
			Case maintenanceNew = new Case();
			maintenanceNew.Subject = 'Routine Maintenance';
			System.debug('### Second: '+mapProduct.get(maintenance.Equipment__c));
			if (mapProduct.get(maintenance.Equipment__c) != null) {
				
				 maintenanceNew.Date_Due__c = Date.today().addDays(Integer.valueOf(mapProduct.get(maintenance.Equipment__c)));
				     
            }
			maintenanceNew.Vehicle__c = maintenance.Vehicle__c;
			maintenanceNew.Product__c = maintenance.Product__c;
			maintenanceNew.ContactId  = maintenance.ContactId;
			maintenanceNew.AccountId  = maintenance.AccountId;
			maintenanceNew.AssetId    = maintenance.AssetId;
			maintenanceNew.Type 	  = 'Routine Maintenance';
			maintenanceNew.Status 	  = 'New';
			maintenanceNew.Equipment__c = maintenance.Equipment__c;
			maintenanceNew.Date_Reported__c = Date.today();


			maintenance_routineList.add(maintenanceNew);
		}

		insert maintenance_routineList;
	}
}

And my testmethod:
 
@isTest
private class MaintenanceRequestHelperTest {
	
	@isTest static void test_method_one() {

		List<Case> caseList = new List<Case>();
		List<Case> secondList = new List<Case>();

		Account acc = new Account();
		acc.Name = 'test';
		insert acc;

		Contact contact = new Contact();
		contact.FirstName = 'test';
		contact.LastName = 'last';
		contact.Email = 'test@test.com';
		contact.AccountId = acc.Id;
		insert contact;

		Vehicle__c vehicle = new Vehicle__c();
		vehicle.Name = 'car';
		insert vehicle;

		Product2 product = new Product2();
		product.Name = 'test';
		product.isActive = true;
		product.Maintenance_Cycle__c = 2;
		product.Replacement_Part__c = true;
		insert product;

		for(Integer i=1;i<=1000;i++){
			Case maintenanceNew             = new Case();
			maintenanceNew.Subject          = 'Other';
			maintenanceNew.Vehicle__c       = vehicle.Id;
			maintenanceNew.Product__c       = product.Id;
			maintenanceNew.ContactId        = contact.Id;
			maintenanceNew.AccountId        = acc.Id;
			maintenanceNew.Type             = 'Other';
			maintenanceNew.Status           = 'New';
			maintenanceNew.Equipment__c     = product.Id;
			maintenanceNew.Date_Reported__c = Date.today();
			maintenanceNew.Date_Due__c      = Date.today();

			caseList.add(maintenanceNew);	
		}

		insert caseList;
		System.assertEquals(1000,caseList.size());

		for(Case cas:caseList){
			//update information
			cas.Type = 'Repair';
			cas.Status = 'Closed';
			secondList.add(cas);
		}

		update secondList;
		List<Case> createdCases = [Select Id from Case where Type = 'Routine Maintenance'];
		System.assertEquals(1000,createdCases.size());
	
	}	
}

Can someone help me to undestand what I'm missing?.  Thanks in advance.

Edgar,
 
Edgar MoranEdgar Moran
I was able to solve it, when trailhead runs the testing is doing a count query to Cases based on the Subject, I didn't put the subject when the case is created as new. So with that I could solve it.
Sudhir Kumar 19Sudhir Kumar 19
It did not work for me. Any help appreciated!
themaxworldthemaxworld
Here is the code for bulk scenario testing which worked for me. Please note that I also have separate method to cover positive and negative scenarios. 
//bulk test scenario
    @isTest static void testBulkScenario(){
        List<Case> bulkCases = new List<Case>();
        List<Vehicle__c> bulkVehicle = new List<Vehicle__c>();
        List<Product2> bulkEquipment = new List<Product2>();
        List<Work_Part__c> bulkWorkPart = new List<Work_part__c>();
                      
        for(integer i=0; i<300; i++){
            bulkVehicle.add(new Vehicle__c(Name='Test Vehicle-'+i));
            bulkEquipment.add(new Product2(Name='Test Equipment-'+i, Replacement_Part__c = True, 
                                           Current_Inventory__c =(i*5)+100, Maintenance_Cycle__c=i*5, Lifespan_Months__c=i*10,
                                           Cost__c = i*100, Warehouse_SKU__c='9999'+i
                                          ));            
        }
        insert bulkVehicle;
        insert bulkEquipment;
        
        for(integer i=0; i<300; i++){
            bulkCases.add(new Case(Subject='Test Case -'+i, Type='Repair', Status='New', Origin='Web',
                                  Equipment__c=bulkEquipment[i].Id, Vehicle__c = bulkVehicle[i].Id,Date_Reported__c=Date.today(),
                                  Date_Due__c = Date.today()));
        }
        
        insert bulkCases;
        integer counter =0;
        for(Case tCase: bulkCases){
            if(counter/2==0){
                Work_Part__c workPart = new Work_Part__c(Maintenance_Request__c=tCase.Id, 
                                                         Equipment__c=bulkEquipment[counter].Id);
                bulkWorkPart.add(workPart);
            }
            counter++;
        }
        insert bulkWorkPart;
        
        // test the trigger
        for(Case tCase: bulkCases){
            tCase.Status ='Closed';
        }
        update bulkCases;
        
        // check it out
        System.assertEquals(300, [Select Id from Case where type='Routine Maintenance' and Status!='Closed' and Vehicle__c in :bulkVehicle].size());
        System.assertEquals(0, [Select Id from Case where type='Repair' and Status!='Closed' and Vehicle__c in :bulkVehicle].size());
    }
rajesh repswalrajesh repswal
Hi @Edgar Moran, Can you please send me complete code of this "Unlock the Apex Specialist Superbadge"
Thanks in advance. 

Regards,
Rajesh
Prem Kumar 70Prem Kumar 70
You have to insert as many work parts records for each inserted new case record.

Here's my code for helper class:
public class MaintenanceRequestHelper {
    public static void updateWorkOrders(Map<Id,Case> cOldMap, Map<Id,Case> cNewMap){
        List<Id> caseToProcessIdList = new List<Id>();
        Map<Id,List<Work_Part__c>> caseIdToWpMap = new Map<Id,List<Work_Part__c>>();
        Map<Integer,Case> insertCaseMap = new Map<Integer,Case>();
        Map<Integer,List<Work_Part__c>> insertWpMap = new Map<Integer,List<Work_Part__c>>();
        List<Work_Part__c> insertAllWpList = new List<Work_Part__c>();
        Integer commonKey = 0;
        for(Id csId : cNewMap.keySet()){
            if(cOldMap.get(csId).status != 'Closed' && cNewMap.get(csId).status == 'Closed' && (cNewMap.get(csId).type == 'Repair' || cNewMap.get(csId).type == 'Routine Maintenance'))
                caseToProcessIdList.add(csId);
        }
        if(caseToProcessIdList.size() == 0)
            return;
        for (Work_Part__c wp: [Select Id, Name, Equipment__c, Equipment__r.Maintenance_Cycle__c, Maintenance_Request__c, Quantity__c From Work_Part__c Where Maintenance_Request__c IN :caseToProcessIdList]) {
            if(!caseIdToWpMap.containsKey(wp.Maintenance_Request__c))
                caseIdToWpMap.put(wp.Maintenance_Request__c, new List<Work_Part__c>{wp});
            else{
                List<Work_Part__c> tempList = caseIdToWpMap.get(wp.Maintenance_Request__c);
                tempList.add(wp);
                caseIdToWpMap.put(wp.Maintenance_Request__c, tempList);
            }
        }
        for(Id csId : caseToProcessIdList){
            List<Work_Part__c> relatedWpList = caseIdToWpMap.get(csId);
            List<Work_Part__c> insertWpList = new List<Work_Part__c>();
            Integer minDays;
            if(relatedWpList==null || relatedWpList.size()==0){
                relatedWpList = new List<Work_Part__c>();
                minDays = 0;
            }            
            for(Work_Part__c wp : relatedWpList){
                if(minDays == null || minDays >= wp.Equipment__r.Maintenance_Cycle__c.intValue())
                    minDays = wp.Equipment__r.Maintenance_Cycle__c.intValue();
                insertWpList.add(new Work_Part__c(Equipment__c=wp.Equipment__c, Quantity__c=wp.Quantity__c));
            }
            Case oldCase = cNewMap.get(csId);
            Case cse = new Case();
            cse.Type ='Routine Maintenance';
            cse.Status ='New';
            cse.Origin =oldCase.Origin;
            cse.Vehicle__c = oldCase.Vehicle__c;
            cse.Equipment__c = oldCase.Equipment__c;
            cse.Subject = String.isBlank(oldCase.Subject) ? 'subject' : oldCase.Subject;
            cse.Date_Reported__c = System.today();
            cse.Date_Due__c = System.Today().addDays(minDays);
            insertCaseMap.put(commonKey, cse);
            insertWpMap.put(commonKey, insertWpList);
            commonKey++;
        }
        insert insertCaseMap.values();
        for(Integer i : insertCaseMap.keySet()){
            for(Work_Part__c wp : insertWpMap.get(i)){
                wp.Maintenance_Request__c = insertCaseMap.get(i).Id;
                insertAllWpList.add(wp);
            }
        }
        insert insertAllWpList;
    }
}

 
Amitesh PataraAmitesh Patara
Please Guide me.. I have complete Idea of this coding bt I am not getting what to do before writing this code exactly for this challenge. what objects I have to make all those things..Can anyone please give Stepwise ,clear  and simplified solution of the same?
 
voleti venkateshvoleti venkatesh
check if u have creted a process builder , i did create a proces builder and deactivated and it worked for me
Shiwali NagreShiwali Nagre
HI ,
I have got  test class run successfully  but still  not  able to pass the  challenge.
Following error I got.

Challenge Not yet complete... here's what's wrong:
Inserting a new Maintenance Request of type 'Routine Maintenance' and then closing it did not create of a new Maintenance Request based upon the original record correctly. The challenge is expecting to find the closed Maintenance Request plus an 'New' Maintenance Request of type 'Routine Maintenance' with the same Vehicle as the closed one.
Close errors