Apex Coding Interview Challenge #3

Coding question asked by Google

Develop a Trigger on asset to count the amount of assets for a specific account. The value of the asset should increate on insert or undeleteand decrease on delete or reparent to a new account.

Assumption: an asset cannot have a null AccountId, validation rule will fail and not save the record. Asset should always have a lookup to an account.

Apex Asset Trigger

trigger AssetTrigger on Asset (after insert, after update, after delete, after undelete) {
    
    Integer incDecVal = 1;
    if (Trigger.isDelete){
        incDecVal = -1;
    }
    
    AssetHelper.countAccountAssets(trigger.newMap, trigger.oldMap, incDecVal);
}

Apex asset helper class

public with sharing class AssetHelper {
 
     public static void countAccountAssets(Map<Id, Asset> newAssets, Map<Id, Asset> oldAssets, Integer incrementDecrementVal){
         Set<Id> accountIds = new Set<Id>();
         
         if (newAssets!=null){
            for (Asset newAsset : newAssets.values())
                 accountIds.add(newAsset.AccountId);
            
         }
         
         if (oldAssets!=null){
            for (Asset oldAsset : oldAssets.values())
               accountIds.add(oldAsset.AccountId);
         }
             
         Map<Id, Account> accountMap = new Map<Id, Account>([Select Id, Total_Assets__c from Account where Id IN :accountIds]);
         
         Set<Account> updateAccountSet = new Set<Account>();
         
         if (newAssets!=null){
           for (Id newAssetId : newAssets.keySet()){
             Asset newAsset = newAssets.get(newAssetId);
             if (accountMap.containsKey(newAsset.AccountId)){
                 Account updateAccount = accountMap.get(newAsset.AccountId);
                 updateAccount.Total_Assets__c += incrementDecrementVal;
                 
                 if (updateAccount.Total_Assets__c < 0){
                  updateAccount.Total_Assets__c = 0;
                 }
                 
                 updateAccountSet.add(updateAccount);
             }
           }
         }
         
    
         if (oldAssets!=null){
           for (Id oldAssetId : oldAssets.keySet()){
             Asset oldAsset = oldAssets.get(oldAssetId);
             
             if (accountMap.containsKey(oldAsset.AccountId)){
                 Account updateAccount = accountMap.get(oldAsset.AccountId);
                 if (newAssets!=null && newAssets.containsKey(oldAssetId)){
                     Asset newAsset = newAssets.get(oldAssetId);
                     if (oldAsset.AccountId!=newAsset.AccountId){
                         updateAccount.Total_Assets__c -= incrementDecrementVal;
                     }
                 } else {
                     updateAccount.Total_Assets__c += incrementDecrementVal;
                 }
                 
                 if (updateAccount.Total_Assets__c < 0){
                  updateAccount.Total_Assets__c = 0;
                 }
                 
                 updateAccountSet.add(updateAccount);
             }
           }
         } 
        
         Savepoint sp = Database.setSavePoint();
         try{
             Database.update(new List<Account>(updateAccountSet));
         } catch(DMLException ex){
             Database.rollback(sp);
         }
     }
}

Apex asset helper test class

@isTest public class AssetHelperTest {

    @TestSetup static void setupAssetAccount(){
        Account setupAccount = new Account(Name='Test Account', Total_Assets__c=0);
        insert setupAccount;
        
        Asset setupAsset = new Asset(AccountId=setupAccount.Id, Name='Test Asset Setup');
        insert setupAsset;
    }
    
    @isTest static void testInsertAsset(){
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 1);
    }
    
    @isTest static void testDeleteAsset(){
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 1);
        Test.startTest();
            delete [Select Id from Asset][0];
        Test.stopTest();
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 0);
    }
    
    @isTest static void testUnDeleteAsset(){
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 1);
        Asset deleteAsset = [Select Id from Asset][0];
        delete deleteAsset;
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 0);
        Test.startTest();
            undelete deleteAsset;
        Test.stopTest();
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 1);
    }
    
    @isTest static void testReparent(){
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 1);
        
        Account newAccount = new Account(Name='New Account', Total_Assets__c=0);
        insert newAccount;
        
        Asset updateAsset = [Select Id, AccountId from Asset][0];
        updateAsset.AccountId = newAccount.Id;
        
        Test.startTest();
            update updateAsset;
        Test.stopTest();
        
        System.assertEquals([Select Total_Assets__c from Account][0].Total_Assets__c, 0);
        System.assertEquals([Select Total_Assets__c from Account where Id=:newAccount.Id][0].Total_Assets__c, 1);
    }
}