Apex Triggers - 15 (Amazon Interview Question)
1. Scenario Overview
This automation solves an Amazon Interview Question based on a parent-child relationship between a parent object,
Tax_Firm__c, and a child object, Employee__c . The parent features two currency fields: Max_Salary__c and Min_Salary__c . The system must dynamically recalculate and roll up the highest and lowest employee salary values to these parent fields whenever any child employee record is inserted, updated, deleted, or undeleted .Additionally, the solution handles the edge case where all related employees are deleted from a firm, safely resetting the parent summary values to zero instead of leaving stale metrics behind .
or
Show the Min & Max Salary of Employee records on the Parent Company record.
2. Apex Handler Class
java
public class EmployeeTriggerHandler {
public static void updateSalaryRollups(List<Employee__c> newEmployees, Map<Id, Employee__c> oldEmployeeMap) {
Set<Id> taxFirmIds = new Set<Id>();
// Step 1: Collect impacted Parent Tax Firm IDs across various record lifecycles
if (newEmployees != null) {
for (Employee__c emp : newEmployees) {
if (emp.Tax_Firm__c != null) {
taxFirmIds.add(emp.Tax_Firm__c);
}
// Handle lookup re-parenting changes: track the previous parent record
if (oldEmployeeMap != null && oldEmployeeMap.containsKey(emp.Id)) {
Employee__c oldEmp = oldEmployeeMap.get(emp.Id);
if (oldEmp.Tax_Firm__c != null && oldEmp.Tax_Firm__c != emp.Tax_Firm__c) {
taxFirmIds.add(oldEmp.Tax_Firm__c);
}
}
}
}
if (taxFirmIds.isEmpty()) {
return;
}
// Step 2: Initialize map with default zero-out records for all tracked firms to handle total deletions
Map<Id, Tax_Firm__c> taxFirmsToUpdateMap = new Map<Id, Tax_Firm__c>();
for (Id firmId : taxFirmIds) {
Tax_Firm__c defaultFirm = new Tax_Firm__c();
defaultFirm.Id = firmId;
defaultFirm.Max_Salary__c = 0;
defaultFirm.Min_Salary__c = 0;
taxFirmsToUpdateMap.put(firmId, defaultFirm);
}
// Step 3: Run aggregate query to find the actual min and max values for firms that have employees
List<AggregateResult> groupedResults = [
SELECT Tax_Firm__c firmId, MAX(Salary__c) maxSal, MIN(Salary__c) minSal
FROM Employee__c
WHERE Tax_Firm__c IN :taxFirmIds AND Salary__c != null
GROUP BY Tax_Firm__c
];
// Step 4: Populate calculated values into the update map, overwriting defaults where employees exist
for (AggregateResult ar : groupedResults) {
Id firmId = (Id)ar.get('firmId');
Tax_Firm__c firmRecord = taxFirmsToUpdateMap.get(firmId);
firmRecord.Max_Salary__c = (Decimal)ar.get('maxSal');
firmRecord.Min_Salary__c = (Decimal)ar.get('minSal');
}
// Step 5: Perform bulk DML operation outside of loops
if (!taxFirmsToUpdateMap.isEmpty()) {
update taxFirmsToUpdateMap.values();
}
}
}
Use code with caution.
3. Apex Trigger
java
trigger EmployeeTrigger on Employee__c (after insert, after update, after delete, after undelete) {
// Route records to handler processing frameworks inside after-commit lifecycle stages
if (Trigger.isAfter) {
if (Trigger.isInsert || Trigger.isUndelete) {
EmployeeTriggerHandler.updateSalaryRollups(Trigger.new, null);
} else if (Trigger.isUpdate) {
EmployeeTriggerHandler.updateSalaryRollups(Trigger.new, Trigger.oldMap);
} else if (Trigger.isDelete) {
EmployeeTriggerHandler.updateSalaryRollups(Trigger.old, null);
}
}
}
Comments
Post a Comment