Conquering Apex Specialist

November 5, 2019

(11/05/2019 -11/10/19)

Very Exhaustive & tiring challenge. A lot of concepts to digest, definitely could not make it without trailhead and other google resources.

It took me 5 days with an average of 1+ Hour daily.

I still feel I am far away from where I would want to be with coding. I would love to be in a state where I don’t refer to trailhead or google resources. I guess practice is the only way forward…

1. Automate Record Creation (11/05/2019 5 am to 6 am)

What I Learned

https://trailhead.salesforce.com/en/content/learn/modules/apex_triggers

trigger MaintenanceRequest on Case (before update, after update) {
    // call MaintenanceRequestHelper.updateWorkOrders  
    if (trigger.isAfter){
        //if(trigger.isUpdate){
            MaintenanceRequestHelper.updateWorkOrders(Trigger.new,Trigger.OldMap);
            
        }
    }
public class MaintenanceRequestHelper {
    
    public static void updateWorkOrders(List<Case> ClosedCases,map<id,Case> ClosedCasesOldMap){
        // update workorders
        for (Case c : ClosedCases){
        
        Case oldCase = ClosedCasesOldMap.get(c.id);
        
        //https://www.sfdc99.com/2014/02/25/comparing-old-and-new-values-in-a-trigger/
        
        Boolean oldCaseisClosed = oldCase.Status.equals('Closed');
        System.debug('OldCaseisClosed=' + oldCaseisClosed);
        Boolean NewCaseisClosed = C.Status.equals('Closed');
        System.debug('NewCaseisClosed=' + NewCaseisClosed);
        List<AggregateResult> minMaintananceCyleDays = [SELECT MIN(Maintanance_cycle__c) from Work_Part__C where Maintenance_Request__c =: oldCase.id];
        Integer intminMaintananceCyleDays = Integer.valueOf(minMaintananceCyleDays[0].get('expr0'));
        System.debug('intminMaintananceCyleDays = ' + intminMaintananceCyleDays);
        List <Case> CasetobeCreated = new List<case>();
        
        
        
        if(!oldCaseisClosed && NewCaseisClosed ){
        
        if(c.IsClosed == true && (c.Type == 'Repair' || c.Type == 'Routine Maintenance')){
            
            case nc = new case();
            nc.Type = 'Routine Maintenance';
            nc.Vehicle__c = c.Vehicle__c;
            if (c.Equipment__c != null){
            nc.Equipment__c = c.Equipment__c;
            }
            if (c.Subject != null){
            nc.Subject = c.Subject;
        }
            nc.Date_Reported__c = system.today();
            if (intminMaintananceCyleDays != null){
            nc.Date_Due__c = system.today()+ intminMaintananceCyleDays;
            } else 
            nc.Date_Due__c = system.today();
            System.debug('NC: '+ nc);
            nc.Status = 'New';
            CasetobeCreated.add(nc);
            
        }
            insert CasetobeCreated;
        
        }
    }

}
    }        
    

2. Synchronize Salesforce data with an external system

What I Learned

https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_rest_callouts

https://trailhead.salesforce.com/en/content/learn/modules/asynchronous_apex/async_apex_future_methods

public with sharing class WarehouseCalloutService {

    private static final String WAREHOUSE_URL = 'https://th-superbadge-apex.herokuapp.com/equipment';
    
    
    // complete this method to make the callout (using @future) to the
    // REST endpoint and update equipment on hand.
    @Future(callout=true)
    public static void runWarehouseEquipmentSync(){
        List<Product2> syncprod = new List<Product2>();
        
        Http http = new Http();
        HttpRequest request  = new HttpRequest();
        request.setEndpoint(WAREHOUSE_URL);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        
        if(response.getStatusCode()==200){
            
        
            List<equipmentjson> results = (List<equipmentjson>) JSON.deserialize(response.getBody(), List<equipmentjson>.class);
            
            for(equipmentjson inst : results){
                product2 equip = new product2();
                equip.Cost__c = inst.cost;
                equip.Lifespan_Months__c = inst.lifespan;
                equip.Maintenance_Cycle__c = inst.maintenanceperiod;
                equip.Name = inst.name;
                equip.Current_Inventory__c = inst.quantity;
                equip.Replacement_Part__c = inst.replacement;
                equip.Warehouse_SKU__c = inst.sku;
                
                syncprod.add(equip);
            }
            
            }
        if(syncprod != null && syncprod.size() > 0){
            UPSERT syncprod Warehouse_SKU__c;
        }
            
    }
           
    private class equipmentjson{
        private String id;
        private Integer cost;
        private Integer lifespan;
        private Integer maintenanceperiod;
        private String name;
        private Integer quantity; 
        private boolean replacement;
        private String sku;          
    }

            
        }
        
        
        
        
    

global class WarehouseSyncSchedule implements schedulable {
  // implement scheduled code here
  global void execute(SchedulableContext sc){

      WarehouseCalloutService.runWarehouseEquipmentSync();
      
  }
}

4.  Test automation logic 

https://trailhead.salesforce.com/en/content/learn/modules/apex_testing

@isTest
public class TestDataFactory {
    public static List<case> createmr(String mrtype, integer noofcases){
        List<case> mr = new List <case>();
        if(noofcases > 0 && mrtype.length() >0 ){
            
            //create vehicle
            
            Vehicle__c v = new Vehicle__c(Name='Jetta 01', VIN_Number__c='Jetta123');
            insert v;
            
            //create Equipments: two with different maintenance cycles  
            
            List<Product2> equip = new List<Product2>();  
       		equip.add(new Product2(Name='Testequip 01', Warehouse_SKU__c='001', Lifespan_Months__c=12, Maintenance_Cycle__c=60, Replacement_Part__c=true));  
       		equip.add(new Product2(Name='Testequip 02', Warehouse_SKU__c='002', Lifespan_Months__c=24, Maintenance_Cycle__c=30, Replacement_Part__c=true));  
       	    insert equip; 
            
            //create maintenance requests  
         	for (integer i = 0; i<noofcases; i++) {  
         			mr.add(new Case(Type = mrtype, Status='New', Origin='Phone', Equipment__c=equip[0].id, Subject='Test Case'));  
                          }
            insert mr;
        	//Add two work parts for each maintenance request created  
       
            List<Work_Part__c> wp = new List<Work_Part__c>();  
       
           for (Case c: mr) {  
             
             wp.add(new Work_Part__c(Equipment__c=equip[0].id, Maintenance_Request__c=c.id, Quantity__c=1));  
             wp.add(new Work_Part__c(Equipment__c=equip[1].id, Maintenance_Request__c=c.id, Quantity__c=2));  
                             
           }  
       insert wp;  
        }
        
        
        return mr;
        
        
        
    }

}
@IsTest  
 public class MaintenanceRequestTest {  
   @IsTest  
   static void TestPositiveSingle() {  
     //Test Repair maintance request  
     testmrcreation('Repair', 1, 'Closed');  
     //Test Routine Maintenance request  
     testmrcreation('Routine Maintenance', 1, 'Closed');  
   }  
   @IsTest  
   static void TestNegativeSingle() {  
     //Test Other maintance request  
     testmrcreation('Other', 1, 'Closed');  
     //Test Repair maintance request  
     testmrcreation('Repair', 1, 'Working');  
     //Test Routin Maintenance request  
     testmrcreation('Routine Maintenance', 1, 'Escalated');  
   }  
   @IsTest  
   static void TestPositiveBulk() {  
     //Test Repair maintance request  
     testmrcreation('Routine Maintenance', 300, 'Closed');  
     //Test Repair maintance request  
     testmrcreation('Repair', 300, 'Closed');  
   }  
   @IsTest  
   static void TestNegativeBulk() {  
     //Test Other maintance request  
     testmrcreation('Other', 300, 'Closed');  
     //Test Repair maintance request  
     testmrcreation('Repair', 300, 'Working');  
     //Test Routin Maintenance request  
     testmrcreation('Routine Maintenance', 300, 'Escalated');  
   }  
   private static void testmrcreation(string requestType, integer totalCount, string newStatus) {  
     //Test Repair maintance request  
     List<Case> testRequests = TestDataFactory.createmr(requestType, totalCount);  
     for (Case tr: testRequests) {  
       tr.Status = newStatus;  
     }  
     update testRequests;  
     List<Case> newmrs = [SELECT id, Type, Status, Vehicle__c, Equipment__c, Subject, Origin, Date_Reported__c, Date_Due__c  
                      FROM Case WHERE ParentId IN: testRequests   
                      AND Status = 'New'];  
     integer expectedTotal = 0;  
     if(newStatus == 'Closed' && (requestType =='Repair' || requestType == 'Routine Maintenance')) {  
       expectedTotal = totalCount;  
     }  
     // System.assertEquals(expectedTotal,newFollowupRequests.size());  
     if (expectedTotal>0) {  
       for (Case newmr: newmrs) {  
         System.assertEquals('Routine Maintenance', newmr.Type);  
         System.assertEquals('System Generated Routine Maintenance', newmr.Subject);  
         System.assertEquals('System', newmr.Origin);  
         System.assertEquals(Date.today(), newmr.Date_Reported__c);  
         System.assertEquals(Date.today().addDays(30), newmr.Date_Due__c);  
       }  
     }  
   }  
 }  

5. Test Call out Logic

https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_rest_callouts

global class WarehouseCalloutServiceMock implements HttpCalloutMock {
    // implement http mock callout
    //Mock responce created  to test the call out
    global HttpResponse respond(HttpRequest request){
        System.assertEquals('https://th-superbadge-apex.herokuapp.com/equipment', request.getEndpoint());
        System.assertEquals('GET', request.getMethod());
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('[{"_id":"55d66226726b611100aaf741","replacement":false,"quantity":5,"name":"Generator 1000 kW","maintenanceperiod":365,"lifespan":120,"cost":5000,"sku":"100003"}]');
        response.setStatusCode(200);
        return response;
    }
}
 @isTest  
 private class WarehouseCalloutServiceTest {  
  // implement your mock callout test here  
   @isTest  
   static void WarehouseEquipmentSync(){  
     Test.startTest();  
     // Set mock callout class   
     Test.setMock(HttpCalloutMock.class, new WarehouseCalloutServiceMock());   
     // This causes a fake response to be sent from the class that implements HttpCalloutMock.   
     WarehouseCalloutService.runWarehouseEquipmentSync();  
     Test.stopTest();    
        
   }  
 }  

6.Test scheduling logic

https://trailhead.salesforce.com/content/learn/modules/asynchronous_apex/async_apex_scheduled

@isTest
public class WarehouseSyncSheduleTest {
@isTest static void WarehousescheduleTest(){
        String scheduleTime = '00 00 01 * * ?';
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new WarehouseCalloutServiceMock());
        String jobID=System.schedule('Warehouse Time To Schedule to Test', scheduleTime, new WarehouseSyncSchedule());
        Test.stopTest();
        //Contains schedule information for a scheduled job. CronTrigger is similar to a cron job on UNIX systems.
        // This object is available in API version 17.0 and later.
        CronTrigger a=[SELECT Id FROM CronTrigger where NextFireTime > today];
        System.assertEquals(jobID, a.Id,'Schedule ');
       
       
    }
}

Completed “App Customization Specialist” SuperBadge

October 13, 2018

So far the best. Its time to build so cool & powerful apps

Completed Security Specialist!!

October 7, 2018

Exhaustive but a good exercise as the world is moving towards security including crms..

As Salesforce suggest, the best way is to write it down on paper…and start ticking of one by one..

Started this super badge on Aug 4th and completed on Oct 4th….was completely on and off but at the end it just took 3 hours of focussed time.

My First Super Badge – Reporting & Dashboard!

November 6, 2017

Highly recommend this SuperBadge, this is more than Real Time Scenario!!

Below is one final dashBoard!

Being Salesforce Admin is just not being able to create Reports and dashboards – It is about how your organization handles Data.

Data comes into Salesforce from Various forms – List Imports, Backend API Integrations and Manual Entry.

This Super badge introduces about how data is imported into salesforce via Data Loader…

I am glad and super excited to have accomplished this dashboard.

Superbadge